Codeforces Round #685 (Div. 2) 题解

题目链接:Codeforces Round #685 (Div. 2)
A. Subtract or Divide

贪心,不难发现除了2的偶数仅有两次操作就行,除了1和3的奇数仅有三次操作;剩下的特判即可。

int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		int n;
		cin >> n;
		if(n%2==0)
		{
			if(n==2) cout << 1 << endl;
			else cout << 2 << endl;
			continue;
		}
		if(n==1) cout << 0 << endl;
		else if(n==3) cout << 2 << endl;
		else cout << 3 << endl;
	}
}

B. Non-Substring Subsequence

贪心判断区间外两边是否有和区间端点相同的字符,相等则YES,否则NO。

char s[maxn];
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		int n,q;
		cin >> n >> q;
		scanf("%s",s+1);
		while(q--)
		{
			int l,r; cin >> l >> r;
			bool flag=false;
			for(int i=1;i<l;i++)
			{
				if(s[i]==s[l])
				{
					flag=true;
					break;
				}
			}
			for(int i=r+1;i<=n;i++)
			{
				if(s[i]==s[r])
				{
					flag=true;
					break;
				}
			}
			if(flag) cout << "YES"<< endl;
			else cout << "NO" << endl;
		}
	}
}

C. String Equality

一开始思路错了,想着统计字符个数,按个数排序判断每个字符的长度关系以及字符大小关系。

ccc
cee

这种样例没法完成,因为上一个字符的操作2后可能有结余用于后面字符的操作,所以得用一个数去记录个数,操作1是相邻互换,所以字符顺序没那么重要,我们可以统计字符个数后,从a~z枚举,注意记录结余个数时需要能被k整除。

map<char,int> book1,book2;
int main()
{
	int t;
	cin >> t;
	while(t--)
		{
			book1.clear();
			book2.clear();
			int n,k;
			cin >> n >> k;
			string a,b;
			cin >> a >> b;
			for(int i=0;i<a.length();i++) book1[a[i]]++;
			for(int i=0;i<b.length();i++) book2[b[i]]++;
			int cnt1=0;
			bool flag=true;
			for(char c='a';c<='z';c++)
			{
				if(book1[c]==book2[c]) continue;
				if(book1[c]>book2[c])
					cnt1+=(book1[c]-book2[c]);
				else
				{
					int tmp=book2[c]-book1[c];
					if(cnt1<tmp || tmp%k)
					{
						flag=false; break;
					}
					cnt1-=tmp;
				}
				if(cnt1%k)
				{
					flag=false; break;
				}
			}
			if(flag) cout << "Yes" << endl;
			else cout << "No" << endl;
		}
}

D. Circle Game

博弈问题,一开始以为sg函数打表找规律类型的问题,结果把d:1~15的表都打出来后,并没有发现什么规律。所以比赛中就没搞出来。<.>
赛后发现是自己思路错了,规律是没有的。。。

其实通过画出决策树我们发现二者一定可以让自己或者对方到达 (tk,tk+k)或(tk+k,tk)的点(t是整数,k是题目给的每次走的步数),我们只需分析当t取最大时这两点的状态就能判断出必胜还是必败态了。

int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		ll d,k;
		cin >> d >> k;
		ll x=d*1.0/sqrt(2)/(k*1.0);
		x*=k;
		if(x*x+(x+k)*(x+k)<=d*d) cout << "Ashish" << endl;
		else cout << "Utkarsh" << endl;
		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值