本来可以AK的一场比赛。
结果因为自己十分脑残,代码各种出错。
事实证明:不能在学校的晚饭时间不吃饭打CF

A. Shell Game
SBT,发现6是一个循环节,膜掉就可以模拟了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
int n,k;
int a[3]={0,1,2};
int main()
{
scanf("%d%d",&n,&k);
n%=6;
F(i,1,n)
{
if (i&1) swap(a[0],a[1]);
else swap(a[1],a[2]);
}
printf("%d\n",a[k]);
}
B. Game of Credit Cards

贪心即可,手残-1
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
int n;
char s1[2005],s2[2005];
int a[2005],b[2005];
int cnt1[11],cnt2[11],ans1,ans2;
int main()
{
scanf("%d",&n);
scanf("%s",s1+1); scanf("%s",s2+1);
F(i,1,n) a[i]=s1[i]-‘0‘,b[i]=s2[i]-‘0‘,cnt1[b[i]]++,cnt2[b[i]]++;
F(i,1,n)
{
int flag=0;
F(j,a[i]+1,9)
{
if (cnt1[j])
{
cnt1[j]--;
ans1++;
flag=1;
break;
}
}
if (flag) continue;
else
{
F(j,0,a[i])
{
if (cnt1[j])
{
cnt1[j]--;
break;
}
}
}
}
F(i,1,n)
{
int flag=0;
F(j,a[i],9)
{
if (cnt2[j])
{
cnt2[j]--;
flag=1;
break;
}
}
if (flag) continue;
else
{
ans2++;
F(j,0,a[i]-1)
{
if (cnt2[j])
{
cnt2[j]--;
break;
}
}
}
}
cout<<ans2<<endl<<ans1<<endl;
}
C. Alyona and Spreadsheet
这题目,遇到N*M<=S的这种条件,简直爆炸。必须要交换nm,分类讨论。简直是二合一题目。
我的做法是如果n大,算一列,扫一遍询问。
如果m打,每次往后算一位,扫一遍询问
垃圾题目,在总共2h的情况下调了1h
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define inf 0x3f3f3f3f
int a[100005][405];
int ans[100005],l[100005],r[100005];
int n,m,k,dp[100005];
int main()
{
scanf("%d%d",&n,&m);
if (n>=m)
{
F(i,1,n) F(j,1,m) scanf("%d",&a[i][j]);
scanf("%d",&k);
F(i,1,k) scanf("%d%d",&l[i],&r[i]);
F(j,1,m)
{
F(i,1,n)
{
if (a[i][j]>=a[i-1][j]) dp[i]=dp[i-1];
else dp[i]=i;
}
F(i,1,k)
if (dp[r[i]]<=l[i])
ans[i]|=1;
}
F(i,1,k)
if (ans[i]) printf("Yes\n");
else printf("No\n");
}
else
{
F(i,1,n) F(j,1,m) scanf("%d",&a[j][i]);
scanf("%d",&k);
F(i,1,k) scanf("%d%d",&l[i],&r[i]);
F(j,1,n)
{
int now=inf;
F(i,1,m)
{
if (a[i][j]<a[i][j-1])
{
dp[i]=j;
}
now=min(now,dp[i]);
}
F(i,1,k)
{
if (r[i]==j&&now<=l[i])
ans[i]|=1;
}
}
F(i,1,k)
if (ans[i]) printf("Yes\n");
else printf("No\n");
}
}
全是细节题目,让我可怎么办
直接扫一遍,比较的时候注意一下,手残把int开成了char,-3还过不了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
char a[5000005],s[1000005];
int l[1000005],r[1000005],now=1;
int n;
int main()
{
scanf("%d",&n);
F(i,1,n)
{
// printf("now is %d\n",i);
scanf("%s",s);
int len=strlen(s+1);
l[i]=now;
F(j,1,len)a[now+j-1]=s[j];
r[i]=now+len-1;
now=r[i]+1;
}
D(i,n-1,1)
{
int l1=r[i]-l[i]+1,l2=r[i+1]-l[i+1]+1;
if (l1<l2)
{
int pos=r[i];
F(j,1,l1)
if (a[j+l[i]-1]>a[j+l[i+1]-1]){pos=j+l[i]-2;break;}
else if (a[j+l[i]-1]<a[j+l[i+1]-1]) break;
r[i]=pos;
}
else if (l1==l2)
{
int pos=r[i];
F(j,1,l1) if (a[j+l[i]-1]>a[j+l[i+1]-1]){pos=j+l[i]-2;break;}
else if (a[j+l[i]-1]<a[j+l[i+1]-1]) break;
r[i]=pos;
}
else
{
int pos=r[i];
F(j,1,l2)
if (a[j+l[i]-1]>a[j+l[i+1]-1]){pos=j+l[i]-2;break;}
else if (a[j+l[i]-1]<a[j+l[i+1]-1]) break;
else if (j==l2) pos=j+l[i]-1;
if (!l2) pos=l[i]-1;
r[i]=pos;
}
}
F(i,1,n)
{
printf("#");
F(j,l[i],r[i]) printf("%c",a[j]);
printf("\n");
}
}
E. Hanoi Factory
看到题目我慌了。D还没过。
看了看貌似可以按照b排序。
然后发现对于当前的i,我们可以找到后面能落在上面的进行转移
dp[i]=dp[j]+hi,当j可以落在i上,即ai<bj<bi,发现如此做就比较容易了,因为j的约束只剩下bj了。
然后可以用线段树优化,二分可行的范围然后在线段树上查询即可。
手残写挂二分,样例太弱,一直WA on 4
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (ll i=j;i<=k;++i)
#define D(i,j,k) for (ll i=j;i>=k;--i)
#define ll long long
struct node{ll a,b,h;}c[100005];
ll n;
struct Segment_Tree
{
ll mx[(100005)*8],X,C,L,R;
void modify(ll o,ll l,ll r)
{
if (l==r) {mx[o]=C; return ;}
ll mid=l+r>>1;
if (X<=mid) modify(o<<1,l,mid);
else modify(o<<1|1,mid+1,r);
mx[o]=max(mx[o<<1],mx[o<<1|1]);
}
ll qmax(ll o,ll l,ll r)
{
if (L<=l&&r<=R) return mx[o];
ll mid=l+r>>1;
if (L>mid) return qmax(o<<1|1,mid+1,r);
if (R<=mid) return qmax(o<<1,l,mid);
else return max(qmax(o<<1|1,mid+1,r),qmax(o<<1,l,mid));
}
}Tree;
bool cmp(node x,node y)
{return x.b==y.b?x.a>y.a:x.b>y.b;}
int main()
{
scanf("%I64d",&n);
F(i,1,n) scanf("%I64d%I64d%I64d",&c[i].a,&c[i].b,&c[i].h);
sort(c+1,c+n+1,cmp);
Tree.X=n;Tree.C=c[n].h;Tree.modify(1,1,n);
D(i,n-1,1)
{
ll l,r,lans=0,rans=n;
l=i+1;r=n;
while (l<r)
{
ll mid=(l+r>>1)+1;
if (c[i].a<c[mid].b) l=mid;
else r=mid-1;
}
if (c[l].b<=c[i].a) l--;
lans=i+1;rans=l;
if (rans<lans)
{
Tree.X=i;Tree.C=c[i].h;
Tree.modify(1,1,n);
continue;
}
Tree.L=lans;Tree.R=rans;
Tree.X=i;Tree.C=Tree.qmax(1,1,n)+c[i].h;
Tree.modify(1,1,n);
}
Tree.L=1;Tree.R=n;
printf("%I64d\n",Tree.qmax(1,1,n));
}
气死我了,看来我不适合打CF

Codeforces Round #401 (Div. 2)
原文:http://www.cnblogs.com/SfailSth/p/6446064.html