cf卡卡的
Codeforces Round 169 (Div. 2)
#博弈游戏
两人轮流删去字符串中的一个字符,如果删去之后,可以重排获得回文字符串,则对方赢。两人都选择最优策略,谁会赢?
重排则不考虑字符顺序,处理所有字符计数。什么样的字符串可以构成回文串?字母计数全是偶数,或者有一个奇数。
如果初始条件如上,那么a赢。
如果有多个奇数呢?ab都会尽量避免白送,不会让对方赢。
比如2 3 3 ->A1 3 3 ->B 0 3 3 ->A 0 2 ->B赢
比如1 1 1 ->A 0 1 1 ->B 0 0 1->A赢
比如 1 1 2->A 1 1 1->…->B赢
偶数没有作用,所有的计数都可以归为0或1。如果有两个以上的奇数,并且计数之和是偶数,那么B赢;如果有两个以上的奇数,并且计数之和是奇数,那么A赢
int cnt[26];
signed main(){
IOS;
string s;cin>>s;
fer(i,0,s.size()){
cnt[s[i]-'a']++;
}
fer(i,0,26){
if(cnt[i]%2==1){
if(s.size()%2==1)cout<<"First"<<endl;
else cout<<"Second"<<endl;
return 0;
}
}
cout<<"First"<<endl;
return 0;
}
Codeforces Round 153 (Div. 1)
#二分
IOS;
int n,d;cin>>n>>d;
fer(i,0,n)cin>>a[i];
int cnt=0;
int l,r;
fer(i,0,n-2){
l=i+2;r=n-1;
while(l<r){
int mid=(l+r+1)>>1;
if(a[mid]-a[i]>d)r=mid-1;
else l=mid;
}
if(a[l]-a[i]<=d){
int tmp=l-i-1;//右端点
cnt+=(1+tmp)*tmp/2;
}
}
cout<<cnt<<endl;
return 0;
}
Codeforces Round 738 (Div. 2)
#位运算
经过一番操作使得序列的最大值最小
按位与只会让数字越来越小,因此把序列的所有数与一遍就是答案
const int N=105,mod=1e9+7;
int a[N];
signed main(){
IOS;
cf{
int n;cin>>n;
fer(i,0,n)cin>>a[i];
int res=a[0];
fer(i,1,n)res=res&a[i];
cout<<res<<endl;
}
return 0;
}
Codeforces Beta Round 87 (Div. 1 Only)
有点像并查集。求多棵树的最大深度
构造树还需要额外的数据结构,这个题n只有2e3,n^2完全可以ac,因此直接简单粗暴遍历一遍
const int N=2e3+1,mod=1e9+7;
int a[N];
signed main(){
IOS;
int n;cin>>n;
fer(i,1,n+1)cin>>a[i];
int mx=0;
fer(i,1,n+1){
int cnt=0;
int now=i;
while(a[now]!=-1){
cnt++;
now=a[now];
}
mx=max(mx,cnt+1);
}
cout<<mx;
return 0;
}
#排序
Codeforces Round 837 (Div. 2)
找出多少对差为最大值的i,j
普通情况是cntl*cntr*2
特殊情况是所有数字一样,cnt*(cnt-1)
const int N=1e5+5,mod=1e9+7;
int a[N];
signed main(){
IOS;
cf{
int n;cin>>n;
fer(i,0,n)cin>>a[i];
sort(a,a+n);
int mx=a[n-1]-a[0];
int cntl=0,cntr=0;
fer(i,0,n){
if(a[i]==a[0])cntl++;
else break;
}
for(int i=n-1;i>=cntl;i--){
if(a[i]==a[n-1])cntr++;
else break;
}
if(cntr==0)cout<<cntl*(cntl-1)<<endl;
else cout<<cntl*cntr*2<<endl;
}
return 0;
}