Codeforces Round #401 (Div. 2)

本来可以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
",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
");
			else printf("No
");
	}
	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
");
			else printf("No
");
	}
}
D. Cloud of Hashtags

 全是细节题目,让我可怎么办

直接扫一遍,比较的时候注意一下,手残把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
",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("
");
	}
}

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
",Tree.qmax(1,1,n));
}

气死我了,看来我不适合打CF

原文地址:https://www.cnblogs.com/SfailSth/p/6446064.html