Educational Codeforces Round 137 (Rated for Div. 2)(补题中)
战绩:
A. Password
列出所有可能的形式,包括AABB,ABAB,ABBA三种,然后在所有可行的数字中选两个进行排列,答案即$3*P_n^2$
当然暴力打表也是可以的,这题居然卡了那么久。
int main() { read(T); while(T--) { read(n); for(int i=1;i<=n;i++) read(k); int lim=3*(10-n)*(10-n-1); cout<<lim<<endl; } return 0; }
B. Permutation Value
由于我们要的是子区间,所以答案是2,输出1然后倒序n到2即可
int main() { read(T); while(T--) { read(n); cout<<1; for(int i=n;i>=2;i--) cout<<" "<<i; cout<<endl; } return 0; }
C. Save the Magazines
对于一长段的1,我们能拯救的实际上只有最靠近它们的左边的那个0,那对于每一段我们统计所有的1的最小值,和那个0的值作比较然后决定是否交换即可。
int main() { read(T); while(T--) { read(n); cin>>s; s='*'+s+'0'; int ans=0; for(int i=1;i<=n;i++) { read(val[i]); if(s[i]=='1') ans+=val[i]; } int pos=-1; for(int i=1;i<=n+1;i++) { if(s[i]=='0') //结算 { if(!que.empty()&&pos!=-1) { int lim=que.top(); ans=max(ans,ans-lim+val[pos]); } while(!que.empty()) que.pop(); pos=-1; } else { if(s[i-1]=='0') pos=i-1; que.push(val[i]); } } cout<<ans<<endl; } return 0; }
D. Problem with Random Tests
亚雷吗,这题最关键的信息是它的数据随机生成,给孩子T麻了。
首先我们要把前导0去除了,那么S1很显然应该是去除之后的这个数字,毕竟它的1位数最高。
然后由于S2是S1的一个子串,我们显然一定要让最左边那个0变为1,这然后再去讨论后面的。
我们截取一小段子串,实际上可以看做从最后一位开始每一位或上其前面第k个数字。
这里是我看到随机生成条件前的做法:
我们可以从左往右,对于每个0,它都有一些偏移值k可以使得它变为1,同时也会有一些偏移值由于要让这一位变为1而失效(和前面的0的偏移值取交集可以让两个都变为1)。
这个k实际上是每一位0之前的所有1和它的相对位置,但是由于我们的0要从高位往低位变化,所以实际上不会太多。
如果在某个0变为1的时候的交集为空,偏移值都失效了,那这一位就无法变为0.
由于是相对位置,所有前面有效的偏移值都会一位位的偏移,那么我们就可以使用bitset进行优化。
但是这样的复杂度最劣的情况是前面一半都是1的情况,就会立刻退化为O(N2/64).
结束之后我才发现数据是随机生成的。。。。。
那这样就意味着前面连续1是很少的,最高位的0只能和前面的1或为1,我们把每一个1都对上这个0然后全都暴力做一遍也不会报。
但是我的复杂度更优(叉腰)
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<cstring> #include<bitset> #define ll long long #define N 501000 using namespace std; int n,m,k,tot,Q,tt,T; string s,s2; bitset<20000>bs,bs2,bs3,bshas; inline void read(int &p) { p=0; int f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();} while(ch>='0'&&ch<='9') {p=p*10+(ch-'0');ch=getchar();} p*=f; } int main() { //read(T); T=1; while(T--) { read(n); cin>>s; tot=0; int tot0=0; bool f=0; tot=0; for(int i=0;i<s.size();i++) { if(s[i]=='0') tot++; if(s[i]=='1') break; } s2=s.substr(tot); if(s2.size()==0) {cout<<0<<endl;continue;} tot=0; for(int i=0;i<s2.size();i++) { if(s2[i]=='1') tot++; if(s2[i]=='0') break; } if(tot>=(s2.size()+1)/2) { for(int i=1;i<=s2.size();i++) cout<<1; cout<<endl; continue; } tot=0; int anstot=0; bool flag=0; for(int i=0;i<s2.size();i++) { bshas<<=1; if(s2[i]=='1') { tot++; bshas[1]=1; } else { if(!flag) { flag=1; bs=bshas; s2[i]='1'; continue; } bs3=(bs&bshas); if(bs3.count()==0) continue; else { bs=bs3; s2[i]='1'; } } } cout<<s2<<endl; } return 0; }