【CodeForces - 768C】Jon Snow and his Favourite Number(思维,技巧,套路,数学异或,循环节,trick)
題干:
Jon Snow now has to fight with White Walkers. He has?n?rangers, each of which has his own strength. Also Jon Snow has his favourite number?x. Each ranger can fight with a white walker only if the strength of the white walker equals his strength. He however thinks that his rangers are weak and need to improve. Jon now thinks that if he takes the bitwise XOR of strengths of some of rangers with his favourite number?x, he might get soldiers of high strength. So, he decided to do the following operation?k?times:
Suppose, Jon has?5?rangers with strengths?[9,?7,?11,?15,?5]?and he performs the operation?1?time with?x?=?2. He first arranges them in the order of their strengths,[5,?7,?9,?11,?15]. Then he does the following:
The new strengths of the?5?rangers are?[7,?7,?11,?11,?13]
Now, Jon wants to know the maximum and minimum strength of the rangers after performing the above operations?k?times. He wants your help for this task. Can you help him?
Input
First line consists of three integers?n,?k,?x?(1?≤?n?≤?105,?0?≤?k?≤?105,?0?≤?x?≤?103) — number of rangers Jon has, the number of times Jon will carry out the operation and Jon's favourite number respectively.
Second line consists of?n?integers representing the strengths of the rangers?a1,?a2,?...,?an?(0?≤?ai?≤?103).
Output
Output two integers, the maximum and the minimum strength of the rangers after performing the operation?k?times.
Examples
Input
5 1 2 9 7 11 15 5Output
13 7Input
2 100000 569 605 986Output
986 605題目大意:
? ?給你一組數,進行k組操作,每組操作中包含兩個步驟,首先排序,然后對下標為奇數的數字進行異或操作。最后問你進行k組操作之后的數組中的最大值和最小值。
解題報告:
不是我就想知道這題打死也想不到會出現循環節的情況吧??!!?這也太、、可能這是異或運算的一種特性?反正我是第一次遇到,題目中會猜他存在循環節然后進行暴力的。。。然后,循環節是4不是2、所以其實代碼中的(ci-3)是不需要進行判斷的。(所以對于這種不知道循環節是幾的這種題,保險起見建議那種精彩代碼,直接Node結構體記錄曾經算過的狀態,并且用vector存下來!!技巧啊)
AC代碼:
#include<bits/stdc++.h> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; int a[MAX]; int mx[MAX],mi[MAX]; int main() {int n,k,x,ci;cin>>n>>k>>x;mx[0]=0,mi[0]=100005;for(int i = 1; i<=n; i++) scanf("%d",a+i),mx[0] = max(mx[0],a[i]),mi[0] = min(mi[0],a[i]);for(ci = 1; ci<=k; ci++) {sort(a+1,a+n+1);mx[ci] = -100005;//a[n];是錯的 mi[ci] = 100005;//a[1];是錯的 for(int i = 1; i<=n; i++) {if(i&1) a[i] = a[i] ^ x;mi[ci] = min(a[i],mi[ci]);mx[ci] = max(a[i],mx[ci]);}if(ci > 4) {if(mi[ci] == mi[ci-1] && mi[ci] == mi[ci-2] && mi[ci] == mi[ci-3] && mi[ci] == mi[ci-4])if(mx[ci] == mx[ci-1] && mx[ci] == mx[ci-2] && mx[ci] == mx[ci-3] && mx[ci] == mx[ci-4]) {printf("%d %d\n",mx[ci],mi[ci]);return 0 ;}}} // sort(a+1,a+n+1);printf("%d %d\n",mx[ci-1],mi[ci-1]);return 0 ;}1WA代碼:
? ?需要i++,而不是i+=2直接做,因為你想啊,你這一輪操作的mx和mi,都是所有數字的,而不是選出來那些數的啊!!另外,不能直接每次都mx[ci] = a[n]這樣,因為這一輪操作之后可能就沒有這個最大值了,可能就被覆蓋成別的值了。,。。所以說啊,寫代碼的時候一定要注意是否代碼中存在小問題,這些問題疊加到一塊就很致命了!!
#include<bits/stdc++.h> #define ll long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 2e5 + 5; int a[MAX]; int mx[MAX],mi[MAX]; int main() {int n,k,x,ci;cin>>n>>k>>x;mx[0]=0,mi[0]=100005;for(int i = 1; i<=n; i++) scanf("%d",a+i),mx[0] = max(mx[0],a[i]),mi[0] = min(mi[0],a[i]);for(ci = 1; ci<=k; ci++) {sort(a+1,a+n+1);mx[ci] = -100005;//a[n];是錯的 mi[ci] = 100005;//a[1];是錯的 for(int i = 1; i<=n; i+=2) {//這樣寫應該也是錯的 a[i] = a[i] ^ x;mi[ci] = min(a[i],mi[ci]);mx[ci] = max(a[i],mx[ci]);}if(ci > 4) {if(mi[ci] == mi[ci-1] && mi[ci] == mi[ci-2] && mi[ci] == mi[ci-3] && mi[ci] == mi[ci-4])if(mx[ci] == mx[ci-1] && mx[ci] == mx[ci-2] && mx[ci] == mx[ci-3] && mx[ci] == mx[ci-4]) {printf("%d %d\n",mx[ci],mi[ci]);return 0 ;}}}sort(a+1,a+n+1);printf("%d %d\n",a[n],a[1]);return 0 ;}?
另一個精彩的代碼:
把每次變化的都存起來。然后得到一個新的狀態的時候,先去跟之前存起來的那些狀態比較,如果發現又相同的狀態,那么就表示找到了循環節了。
之后求出來循環節的長度,然后取模,得到最后的答案。
(代碼中可以直接return 0的,不需要goto,因為是codeforce的題。、。。)
#include <bits/stdc++.h>using namespace std; const int MAXN=1e5+7; int n,k,x; int cnt; struct node { //用來存儲已經出現過的狀態int num[MAXN];int MAX;int MIN;node() {MAX=0;MIN=1e9;}bool operator ==(const node &a)const {for(int i=0; i<n; ++i) {if(a.num[i]!=num[i])return 0;}return 1;} } p; vector<node>q; int check() {for(int i=0; i<cnt; ++i) {if(q[i]==p)return i;}return -1; } int main() {int i; xx:while(~scanf("%d%d%d",&n,&k,&x)) {q.clear();p.MAX=0;p.MIN=1e9;for(i=0; i<n; ++i) {scanf("%d",&p.num[i]);p.MAX=max(p.MAX,p.num[i]);p.MIN=min(p.MIN,p.num[i]);}sort(p.num,p.num+n);q.push_back(p);cnt=0;int pos;while(cnt<k) {cnt++;p.MAX=0;p.MIN=1e9;for(i=0; i<n; i+=2) {p.num[i]^=x;}for(i=0; i<n; ++i) {p.MAX=max(p.MAX,p.num[i]);p.MIN=min(p.MIN,p.num[i]);}sort(p.num,p.num+n);pos=check();if(pos!=-1) { //找到循環節了int t=cnt-pos;//循環節長度k=(k-pos)%t+pos;//取模之后的答案的下標printf("%d %d\n",q[k].MAX,q[k].MIN);goto xx;//找到了就直接重新讀取下一組}q.push_back(p);}printf("%d %d\n",p.MAX,p.MIN);//表示沒有找到循環節}return 0; }?
總結
以上是生活随笔為你收集整理的【CodeForces - 768C】Jon Snow and his Favourite Number(思维,技巧,套路,数学异或,循环节,trick)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【POJ - 2762】Going fr
- 下一篇: *【洛谷 - P1025】数的划分(df