河南省第十屆ACM賽題
阿新 • • 發佈:2019-01-04
本屆賽題難度不是太大,9道題目我們隊一共做了7道拿了個銀,很遺憾沒有能為我們學校帶來首金。
貼上我們隊的ac的程式碼留個紀念,題目我就不一個一個字碼出來了,直接上照片,沒做的題我就不在貼了。。。
A題:諜報分析
A題直接用了stl中的map容器,用起來很方便,但是後果就是執行時間較慢。。
這題在輸入上面較坑。
B題:情報傳遞#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; }
這題是由正式賽前一天的訓練賽的A題加強版,題意半天才看懂,要注意0還有個上司,假設為-1,所以Send 0結果為1,Send 之後的路徑還會存在,並影響下一次操作。
總的來說該題不難,在操作之前先將資料以圖的形式儲存下來,以便Danger操作。
C題:最小金鑰#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; }
這題在解題報告會上,上面的一個阿姨說這題主要是考查一個啥數學公式來著,結果資料太水。都是暴力出來的。
D題:年終獎金#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; }
一個動態規劃類問題,先將資料排序,在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;
}