USACO测试赛4

USACO测试赛4

1.奶牛的学术圈1

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

hash标记

记录每一个数大于等于它的个数有多少,那么如果vh[i]大于等于i时h指数就可以为i,那么只要vh[i]+l可以大于i时h指数就可以为i。

#include <bits/stdc++.h>
using namespace std;

int n,l,c[100010],vh[100010],maxx,h=0; 

int main(){
	freopen("prob1.in","r",stdin);
	freopen("prob1.out","w",stdout); 
	cin >> n >> l;
	for(int i=1;i<=n;++i){
		cin >> c[i];
		vh[c[i]]++;
		maxx=max(maxx,c[i]);
	}
	for(int i=maxx;i>=0;--i)
		vh[i]+=vh[i+1];
	for(int i=0;i<=maxx+1;++i){
		if(vh[i]>=i)
		   h=i;
		else{
			int cha=vh[i-1]-vh[i];
			if(vh[i]+min(l,cha)>=i){
				h=i;  
			}
		}
	}
	cout << h << endl;
	fclose(stdin);
	fclose(stdout);
	return 0;
}

2.奶牛的学术圈2

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
很容易想到,如果两个字符串不是按字典序排列的,那么前一个人及前面所有人的贡献一定大于后一个人及后面所有人的贡献,资历即相反。

#include <bits/stdc++.h>
using namespace std;

int k,n;
string s,st[110];
char vh[110][110];
map<string,int> mymap;

int main(){
	freopen("prob2.in","r",stdin);
	freopen("prob2.out","w",stdout);
	cin >> k >> n;
	for(int i=1;i<=n;++i){
		cin >> s;
		mymap[s]=i;
	}
	for(int i=1;i<=n;++i)
	   for(int j=1;j<=n;++j)
	      vh[i][j]='?';
	for(int i=1;i<=n;++i)
		vh[i][i]='B';
	for(int i=1;i<=k;++i){
		for(int j=1;j<=n;++j)
			cin >> st[j];
		for(int j=1;j<n;++j){
			if(st[j]>st[j+1]){
				for(int p=1;p<=j;++p)
				   for(int q=j+1;q<=n;++q){
				   	  int id1=mymap[st[p]],id2=mymap[st[q]];
				   	  vh[id1][id2]='0';
				   	  vh[id2][id1]='1';
				   }
			}
		}
    }
    for(int i=1;i<=n;++i){
       for(int j=1;j<=n;++j)
       	  cout << vh[i][j];
       cout << endl;
    }
    fclose(stdin);
    fclose(stdout);
	return 0;
} 

3.奶牛的学术圈3

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

贪心

我们先让只有一个格子吃草的奶牛对先吃,有两种方法吃草的奶牛等一等,直到所有奶牛都有两种方法吃草了,再让它们随便选一个吃,并打标记。

#include <bits/stdc++.h>
using namespace std;

int n,m,ans=0;
struct nod{
	int x1;
	int y1,x2,y2,sum;
	nod(int _x1=0,int _y1=0,int _x2=0,int _y2=0,int _sum=0):x1(_x1),y1(_y1),x2(_x2),y2(_y2),sum(_sum){}
};
vector<nod> pos;
char s[1010][1010];
bool vh[1010][1010];

int main(){
	freopen("prob3.in","r",stdin);
	freopen("prob3.out","w",stdout);
	cin >> n >> m;
	for(int i=1;i<=n;++i)
	   for(int j=1;j<=m;++j)
		  cin >> s[i][j];
	for(int i=1;i<=n;++i)
	   for(int j=1;j<=m;++j)
	      if(s[i][j]=='.' || s[i][j]=='C')
	         vh[i][j]=1;
	for(int i=1;i<=n;++i)
	   for(int j=1;j<=m;++j){
	   	  if(i+2<=n)
	   	  if(s[i][j]=='C' && s[i+2][j]=='C' && s[i+1][j]=='G' && vh[i+1][j]==0){
	   	     vh[i+1][j]=1;
	   	     ans++;
	   	  }
	   	  if(j+2<=n)
	   	  if(s[i][j]=='C' && s[i][j+2]=='C' && s[i][j+1]=='G' && vh[i][j+1]==0){
	   	     vh[i][j+1]=1;
	   	     ans++;
	   	  }
	   	  if(i-2>=1)
	   	  if(s[i][j]=='C' && s[i-2][j]=='C' && s[i-1][j]=='G' && vh[i-1][j]==0){
	   	     vh[i-1][j]=1;
	   	     ans++;
	   	  }
	   	  if(j-2>=1)
	   	  if(s[i][j]=='C' && s[i][j-2]=='C' && s[i][j-1]=='G' && vh[i][j-1]==0){
	   	     vh[i][j-1]=1;
	   	     ans++;
	   	  }
	   	  if(s[i][j]=='C' && s[i+1][j+1]=='C'){
	   	  	int cnt=0;
	   	  	if(s[i][j+1]=='G' && vh[i][j+1]==0)
	   	  	  cnt++;
	   	  	if(s[i+1][j]=='G' && vh[i+1][j]==0)
	   	  	  cnt++;
	   	  	
	   	  	pos.push_back(nod(i,j,i+1,j+1,cnt));
	   	  }
	   	  if(s[i][j]=='C' && s[i+1][j-1]=='C'){
	   	  	int cnt=0;
	   	  	if(s[i][j-1]=='G' && vh[i][j-1]==0)
	   	  	  cnt++;
	   	  	if(s[i+1][j]=='G' && vh[i+1][j]==0)
	   	  	  cnt++;
	   	  	pos.push_back(nod(i,j,i+1,j-1,cnt));
	   	  }
	   }
	bool f;
	do{
		f=false;
		for(int i=0;i<pos.size();++i){
			if(vh[pos[i].x1][pos[i].y2]==0 && vh[pos[i].x2][pos[i].y1]==0)
			  continue;
			if(vh[pos[i].x1][pos[i].y2]==0){
				vh[pos[i].x1][pos[i].y2]=1;
				ans++;
				f=true;
			}
			if(vh[pos[i].x2][pos[i].y1]==0){
				vh[pos[i].x2][pos[i].y1]=1;
				ans++;
				f=true;
			}
		}
	}while(f==true);
	for(int i=0;i<pos.size();++i){
		if(vh[pos[i].x1][pos[i].y2]==0){
			vh[pos[i].x1][pos[i].y2]=1;
			ans++;
		}
		else if(vh[pos[i].x2][pos[i].y1]==0){
			vh[pos[i].x2][pos[i].y1]=1;
			ans++;
		} 
	}
	cout << ans << endl;
	fclose(stdin);
	fclose(stdout);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值