1、升序排序;
2、對奇數位的數字與x做異或運算。
輸出k次操作後的最大值和最小值。
思路:直接模擬的話超時,打表發現存在循環節,那麼直接找循環節就行了。
#include <cstdio>
#include <iostream>
#include<cstring>
#include <algorithm>
using namespace std;
int a[100000+50];
int ans[50][100000+50], n;
int Judge(int x) // 返回循環節點
{
for(int i = 0 ; i < x; i++) {
bool flag = true;
for(int j = 0; j < n; j++) {
if(ans[i][j] != ans[x][j]) {
flag = false;
break;
}
}
if(flag) return i;
}
return -1;
}
int main()
{
int k, x;
while(cin >> n >> k >> x) {
for(int i = 0; i < n; i++) {
cin >> a[i];
ans[0][i] = a[i];
}
int node, i;
for(i = 1; i <= k; i++) {
sort(a, a + n);
for(int j = 0; j < n; j++) {
if(j%2 == 0) a[j] ^= x;
ans[i][j] = a[j];
}
node = Judge(i);
if(node != -1) break;
}
int t;
if(k > i) {
int T = i - node; // T即週期
int fin = (k - i) % T; // 週期中第幾個
t = fin + node; // 記得加上循環節節點
}
else t = k;
int maxx = -1e9;
int minn = 1e9;
for(int i = 0; i < n; i++) {
minn = min(minn, ans[t][i]);
maxx = max(maxx, ans[t][i]);
}
cout << maxx << ' ' << minn << endl;
}
}
網上還有一種做法說最後最大值和最小值會趨於穩定,找最後最大和最小不變的做法,也能AC,但我打表找不出來,暫時也想不出這種做法的正確性。
#include <cstdio>
#include <iostream>
#include<cstring>
#include <algorithm>
using namespace std;
int a[100000+50];
int ans[50][100000+50];
int maxx[100000], minn[100000];
int main()
{
int n, k, x;
while(cin >> n >> k >> x) {
for(int i = 0; i < n; i++)
cin >> a[i];
sort(a, a + n);
maxx[0] = a[n-1];
minn[0] = a[0];
for(int i = 1; i <= k; i++) {
sort(a, a + n);
maxx[i] = a[n-1];
minn[i] = a[0];
if(i >= 3 && maxx[i]==maxx[i-1] && maxx[i]==maxx[i-2] && maxx[i]==maxx[i-3] && minn[i]==minn[i-1] && minn[i]==minn[i-2] && minn[i]==minn[i-3]) {
break;
}
for(int j = 0; j < n; j += 2)
a[j] ^= x;
}
sort(a, a + n);
cout << a[n-1] << ' ' << a[0] << endl;
}
}