Comet OJ - Contest #1 部分题解

题目链接:https://cometoj.com/contest/35/problems

 

A.牛吃草问题

#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int mx = 3e2 + 10;
int a[mx],b[mx],rs[mx];
char s[mx][mx];
int main()
{
	int t;scanf("%d",&t);
	while(t--){
		int n,m;
		memset(a,0,sizeof(a));
		scanf("%d%d",&n,&m);
		int r = -1,x,y;
		for(int i=0;ir){
				r = a[i] / 2;
				x = i + 1,y = rs[i] - r + 1; 
			}
		}
		printf("%d %d %d\n",r,x,y);
	} 
	return 0;
}

B. +1 复读

考虑个位数是9和非9的情况,如果是非9的数,那么肯定以该数为右端点的数,+1之后肯定都是一样的。

如果是9的话,明显会多出一位数来,那么结果肯定就是不一样了,所以除此之外还要考虑连续了多少个9,以及前面都是0的情况要减去一个1。

#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int mx = 2e5 + 10;
char s[mx];
int pre[mx],cnt[mx];
int main()
{
	int t;scanf("%d",&t);
	while(t--){
		s[0] = '0';
		scanf("%s",s+1);
		int n = strlen(s+1);
		ll ans = 0;
		for(int i=1;i<=n;i++){
			pre[i] = pre[i-1];
			cnt[i] = 0;
			if(s[i]=='0') pre[i]++;
			if(s[i]=='9') cnt[i] = cnt[i-1] + 1;
		} 
		for(int i=1;i<=n;i++){
			if(s[i]!='9'){ 
				ans++; 
			}else{
				ans += cnt[i]+1;
				if(pre[i-cnt[i]]==i-cnt[i])
				ans--;
			}
		}
		printf("%lld\n",ans);
	} 
	return 0;
}

C.复读游戏

用a[i]表示AA牌中i数字的个数,b[i]表示dream牌中i数字的个数。

那么可以退出当a[i]+b[i]>n时,AA肯定获胜,证明也很简单。

那么dream要如何必胜呢,那么肯定AA要很被动才行,也就是AA手上只有两种牌的情况下且dream手上也刚好也有这两种牌,AA不能把一种牌全部打完,因为这样dream可以在这一种牌最后一张的时候出另一种牌,那么AA肯定就输了,所以AA必输。

#include 
using namespace std;
const int mx = 1e2 + 10;
int a[mx],b[mx];
int main(){
	int t;scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		for(int i=1;i<=20;i++) a[i] = b[i] = 0;
		for(int i=1;i<=n;i++){
			int v;scanf("%d",&v);
			a[v]++;
		}
		for(int i=1;i<=n;i++){
			int v;scanf("%d",&v);
			b[v]++; 
		}
		bool ok = 1;
		for(int i=1;i<=20;i++){
			if(a[i]+b[i]>n) ok = 0;
		} 
		if(!ok){
			puts("AA wins");
			continue;
		}
		int s = 0, w = 0;
		for(int i=1;i<=20;i++){
			if(a[i]) s++;
			if(a[i]&&b[i]) w++;
		}
		if(s==2&&w==2) puts("dreamoon wins");
		else puts("Draw");
	}
} 

 

你可能感兴趣的:(博弈论,贪心,思维题)