河南省第十届ACM赛题

本届赛题难度不是太大,9道题目我们队一共做了7道拿了个银,很遗憾没有能为我们学校带来首金。

贴上我们队的ac的代码留个纪念,题目我就不一个一个字码出来了,直接上照片,没做的题我就不在贴了。。。

A题:谍报分析


A题直接用了stl中的map容器,用起来很方便,但是后果就是运行时间较慢。。

这题在输入上面较坑。

#include<stdio.h>
#include<string.h>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
struct Word
{
	char str[100];
	int count;
}word[1000];
int N=0;
int comp(Word w1,Word w2)
{
	if(w1.count!=w2.count)
			return w1.count>w2.count;
	else
	{
		int a=strcmp(w1.str,w2.str);
		if(a>0)
			return 0;
		else
			return 1;
	}
}
int main()
{
	map<string,int>m;
	map<string,int>::iterator it;
	char str[100];
	while(scanf("%s",str)!=EOF)
	{
		int len=strlen(str);
		if(str[len-1]==','||str[len-1]=='.')
			str[len-1]='\0';
		string s=str;
		m[s]++;
	}
	for(it=m.begin();it!=m.end();it++)
	{
		string s=it->first;
		int count=it->second;
		strcpy(word[N].str,s.c_str());
		word[N++].count=count;
	}
	sort(word,word+N,comp);
	for(int i=0;i<10;i++)
	{
		printf("%s %d\n",word[i].str,word[i].count);
	}
	return 0;
}
B题:情报传递

这题是由正式赛前一天的训练赛的A题加强版,题意半天才看懂,要注意0还有个上司,假设为-1,所以Send 0结果为1,Send 之后的路径还会存在,并影响下一次操作。

总的来说该题不难,在操作之前先将数据以图的形式存储下来,以便Danger操作。

#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
vector<int>map[5100];
int N,M;
int s[5100];
bool vis[5100];
int Dsum;
void Send(int num)
{
	int sum=0;
	while(!vis[num]&&s[num]!=-1)
	{
		sum++;
		vis[num]=true;
		num=s[num];
	}
	printf("%d\n",sum);
}
void Danger(int num)
{
	for(int i=0;i<map[num].size();i++)
	{
		if(vis[map[num][i]])
		{
			vis[map[num][i]]=false;
			Dsum++;
			Danger(map[num][i]);
		}
	}
}
int main()
{
	int i;
	scanf("%d",&N);
	s[0]=-1;
	for(i=1;i<N;i++)
	{
		scanf("%d",&s[i]);
		map[s[i]].push_back(i);
	}
	memset(vis,false,sizeof(vis));
	scanf("%d",&M);
	char str[10];
	int num;
	for(i=1;i<=M;i++)
	{
		scanf("%s",&str[0]);
		scanf("%d",&num);
		if(str[0]=='S')
		{
			Send(num);
		}
		else
		{
			if(!vis[num])
			{
				printf("0\n");
				continue;
			}
			Dsum=1;
			vis[num]=false;
			Danger(num);
			printf("%d\n",Dsum);
		}
	}
	return 0;
}
C题:最小密钥

这题在解题报告会上,上面的一个阿姨说这题主要是考查一个啥数学公式来着,结果数据太水。都是暴力出来的。

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int N;
int s[3050];
bool vis[20010];
bool can(int x)
{
	for(int i=0;i<N;i++)
	{
		if(vis[s[i]%x])
			return false;
		vis[s[i]%x]=true;
	}
	return true;
}
int main()
{
	int T,i;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&N);
		for(i=0;i<N;i++)
		{
			scanf("%d",&s[i]);
		}
		sort(s,s+N);
		int L=N,R=s[N-1];
		for(i=L;i<=R;i++)
		{
			memset(vis,false,sizeof(vis));
			if(can(i))
			{
				printf("%d\n",i);
				break;
			}
		}
	}
	return 0;
}
D题:年终奖金


一个动态规划类问题,先将数据排序,在dp,状态转移方程:dp[i]=min(dp[j]+c+(a[i]-a[j+1])^2,dp[i]);

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAX 1<<31-1
#define min(x,y)(x<y?x:y)
using namespace std;
int a[110];
int dp[110];
int get(int x,int y)
{
	return (x-y)*(x-y);
}
int main()
{
	int n,k,c,i,j;
	while(scanf("%d%d%d",&n,&k,&c)!=EOF)
	{
		for(i=1;i<=n;i++)
		{
			dp[i]=MAX;
		}
		for(i=1;i<=n;i++)
			scanf("%d",&a[i]);
		sort(a+1,a+1+n);
		dp[0]=0;
		for(i=k;i<=n;i++)
		{
			for(j=0;j<=i-k;j++)
			{
				if(j<k&&j!=0)
					continue;
				dp[i]=min(dp[j]+c+get(a[i],a[j+1]),dp[i]);
			}
		}
		printf("%d\n",dp[n]);
	}
	return 0;
}
F题:Binary to Prime

#include<stdio.h>
#include<string.h>
bool isPrimy(int x)
{
	int i;
	for(i=2;i<=x;i++)
	{
		if(x%i==0)
		{
			break;
		}
	}
	if(x==i)
	{
		return true;
	}
	return false;
}
int main()
{
	int s[200],i;
	int count=2;
	for(i=1;i<=155;)
	{
		if(isPrimy(count))
		{
			s[i]=count;
			count++;
			i++;
		}
		else
		{
			count++;
		}
	}
	char str[200];
	int sum;
	while(scanf("%s",str)!=EOF)
	{
		sum=0;
		int len=strlen(str);
		for(i=len-1;i>=0;i--)
		{
			int pos=len-i;
			if(str[i]==1)
			{
				sum+=s[pos];
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}
G 题:Plumbing the depth of lake

简单的深搜问题,难就难在它是一道英文题。。

题目的大概意思就是要你找出相邻的至少两个相同的数的最大值,每个数的斜对角方向也视为与该数相邻。

#include<stdio.h>
#include<string.h>
int dx[]={-1,-1,-1,0,0,1,1,1};
int dy[]={-1,0,1,-1,1,-1,0,1};
int main()
{
	int T,M,N,i;
	int map[55][55];
	scanf("%d",&T);
	while(T--)
	{
		int max=-1;
		scanf("%d%d",&M,&N);
		memset(map,-1,sizeof(map));
		for(i=1;i<=M;i++)
		{
			for(j=1;j<=N;j++)
			{
				scanf("%d",&map[i][j]);
			}
		}
		for(i=1;i<=M;i++)
		{
			for(j=1;i<=N;j++)
			{
				if(max>=map[i][j])
					continue;
				for(int k=0;k<8;k++)
				{
					if(map[i][j]==map[i+dx[k]][j+dy[k]])
					{
						max=map[i][j];
						break;
					}
				}
			}
		}
		printf("%d\n",max);
	}
	return 0;
}
H题:Intelligent Parking Building

这题不知道神奇的队友是怎么翻译出来的。

大概的意思就是有一个停车楼,停车楼里的车需要全部开出去,标号为-1的位置为空,其他的数字为汽车,汽车出库必须要按照数字从小到大的顺序,

每一行是一个环形传送带,每移动一格耗费5分钟,每移动一层消耗10分钟,问你最少耗费多长时间所有的车都可以出去。



#include<stdio.h>
#include<stdlib.h>
int T,h,l,sum,i,j;
struct node
{
	int floor;
	int pos;
}car[2510];
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		sum=0;
		int max=0;
		scanf("%d%d",&h,&l);
		for(i=1;i<=h;i++)
		{
			map[i][0]=1;
			for(j=1;j<=l;j++)
			{
				scanf("%d",&map[i][j]);
				if(map[i][j]!=-1)
				{
					car[map[i][j]].floor=i;
					car[map[i][j]].pos=j;
					if(max<map[i][j])
						max=map[i][j];
				}
			}
		}
		for(i=1;i<=max;i++)
		{
			int floor=car[i].floor;
			int pos=car[i].pos;
			sum+=(2*(floor-1)*10);
			int one=abs(pos-map[floor][0]);
			int other=l-one;
			int Min=one<other?one:other;
			sum+=Min*5;
			map[floor][0]=pos;
		}
		printf("%d\n",sum);
	}
	return 0;
}


  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值