D. Exact Change E. Replace the Numbers G. Subsequences Galore
?因為1和2的數量最大值不是很多,多了的話可以用3代替,那么枚舉1和2的數量然后二分3的數量
int a[110], n;
bitset<10> bit;boolch(int x){for(int i =1;i <= n;i ++){int num = a[i];x*3>= a[i]? num %=3: num -= x*3;while(~num && num <10&& num <= a[i])if(bit[num])num =-1;else num +=3;if(num !=-1)return0;}return1;}intmain(){int t;scanf("%d",&t);while(t --){scanf("%d",&n);for(int i =1;i <= n;i ++)scanf("%d", a+i);int ans =0x3f3f3f3f;for(int i =0;i <=2;i ++)for(int j =0;j <=3;j ++){bit.reset();bit[0]=1;for(int i =1;i <= j;i ++) bit |= bit<<2;for(int j =1;j <= i;j ++) bit |= bit<<1;int l =0, r =(1e9+2)/3+10000;while(l < r)ch(mid)? r = mid : l = mid+1;ans =min(ans, i + j + l);}cout<<ans<<endl;}return0;}
?代碼有注釋,不過也不咋好,主要并查集 + ( x = num[id[x]] ) 這操作我整懵了
int id[N], fa[N], num[N], idx =0;// id[] 是x在num數組的哪個位置 // num[] 是最后答案的數組,其中用并查集來整合 intfind(int u){return fa[u]== u ? u : fa[u]=find(fa[u]);}intmain(){int t;scanf("%d",&t);for(int i =1;i <= t;i ++) fa[i]= i;while(t --){int f, x, y;scanf("%d%d",&f,&x);if(f ==1){ num[++idx]= x;// 加一個數 if(id[x])fa[id[x]]= idx;// 把是x的父親設為新加的這個數的位置。 id[x]= idx;// x 在 idx; }else{scanf("%d",&y);if(x == y)continue;if(!id[y])num[id[x]]= y, id[y]= id[x];// y不存在 -> 把x變成y; else fa[id[x]]= id[y];// y存在 -> 把x指向y; id[x]=0;// 消除x存在的痕跡。 }}for(int i =1;i <= idx;i ++)printf("%d ", num[find(i)]);return0;}