您的位置:首页 > 其它

河南省第十届ACM赛题

2017-05-08 16:56 405 查看
本届赛题难度不是太大,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
.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
);
}
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的位置为空,其他的数字为汽车,汽车出库必须要按照数
4000
字从小到大的顺序,

每一行是一个环形传送带,每移动一格耗费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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息