哈尔滨理工大学软件与微电子学院第八届程序设计竞赛同步赛(高年级)

A.小乐乐的组合数+:根据等差数列来暴力枚举起点即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 int n,m,a[]={0,6,5,4,3,2,1};LL cnt;
 5 int main(){
 6     while(cin>>n>>m){
 7         if(n>m)swap(n,m);
 8         cnt=0;
 9         for(int i=1;i<=n;++i)
10             cnt+=(m-a[i%7])/7+(i%7>0);
11         cout<<cnt<<endl;
12     }
13     return 0;
14 }
View Code

B.小乐乐搭积木:基础状压dp。

递推:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<string.h>
 4 using namespace std;
 5 typedef long long LL;
 6 const int maxn=15;
 7 const LL mod=1e9+7;
 8 LL dp[2][1<<11];int n,m;
 9 int main(){
10     while(cin>>n>>m){
11         if(n*m&1){cout<<0<<endl;continue;}
12         if(n>m)swap(n,m);
13         memset(dp,0,sizeof(dp));
14         LL *cur=dp[0],*next=dp[1];cur[0]=1;
15         for(int j=0;j<m;++j){
16             for(int i=0;i<n;++i){
17                 memset(dp[(j*n+i+1)&1],0,sizeof(dp[(j*n+i+1)&1]));
18                 cur=dp[(j*n+i)&1],next=dp[(j*n+i+1)&1];
19                 for(int used=0;used<(1<<n);++used){
20                     if((used>>i)&1)next[used&~(1<<i)]+=cur[used];///不需要摆放
21                     else{
22                         if(j+1<m)next[used|(1<<i)]+=cur[used];///尝试横着放
23                         if(i+1<n&&!((used>>(i+1))&1))next[used|(1<<(i+1))]+=cur[used];///尝试竖着放
24                     }
25                 }
26             }
27         }
28         cout<<next[0]<<endl;
29     }
30     return 0;
31 }
View Code

递归:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<string.h>
 4 using namespace std;
 5 typedef long long LL;
 6 const int maxn=13;
 7 const LL mod=1e9+7;
 8 int n,m;LL dp[maxn][1<<11];
 9 void dfs(int j,int i,int state,int nex){
10     if(i==n){dp[j+1][nex]+=dp[j][state];return;}
11     if(((1<<i)&state)>0)
12         dfs(j,i+1,state,nex);
13     if(((1<<i)&state)==0)
14         dfs(j,i+1,state,nex|(1<<i));
15     if(i+1<n&&((1<<i)&state)==0&&((1<<(i+1))&state)==0)
16         dfs(j,i+2,state,nex);
17 }
18 int main(){
19     while(cin>>n>>m){
20         if(n*m&1){cout<<0<<endl;continue;}
21         if(n>m)swap(n,m);
22         memset(dp,0,sizeof(dp)),dp[1][0]=1;
23         for(int j=1;j<=m;++j)
24             for(int i=0;i<(1<<n);++i)
25                 if(dp[j][i])dfs(j,0,i,0);
26         cout<<dp[m+1][0]<<endl;
27     }
28     return 0;
29 }
View Code

C.小乐乐玩木桶:短板原理。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 int n,s,x,ans;
 5 int main(){
 6     while(cin>>n>>s){
 7         cin>>x,ans=x;
 8         while(--n){cin>>x,ans=min(x,ans);}
 9         cout<<ans*s<<endl;
10     }
11     return 0;
12 }
View Code

D.小乐乐玩木桶+:排序取倒数第三个即可。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 int n,s,x[1005];
 5 int main(){
 6     while(cin>>n>>s){
 7         for(int i=0;i<n;++i)cin>>x[i];
 8         sort(x,x+n);
 9         cout<<x[n-3]*s<<endl;
10     }
11     return 0;
12 }
View Code

E.小乐乐匹配字符串:最长公共子序列。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn=1005;
 5 char s1[maxn],s2[maxn];int dp[maxn][maxn],ans,len1,len2;
 6 int main(){
 7     while(cin>>s1>>s2){
 8         memset(dp,0,sizeof(dp));ans=0,len1=strlen(s1),len2=strlen(s2);
 9         for(int i=1;i<=len1;++i){
10             for(int j=1;j<=len2;++j){
11                 if(s1[i-1]==s2[j-1])dp[i][j]=dp[i-1][j-1]+1;
12                 else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
13                 ans=max(ans,dp[i][j]);
14             }
15         }
16         cout<<ans<<endl;
17     }
18     return 0;
19 }
View Code

F.小乐乐下象棋:定义dp[k][x][y]表示走k步到坐标(x,y)的方案数。

递推:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn=220;
 5 const LL mod=1e9+7;
 6 int n,m,k,nx,ny,dir[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};LL dp[2][maxn][maxn];
 7 inline void print(LL x){
 8     if(x<0)putchar('-'),x=-x;
 9     if(x>9)print(x/10);
10     putchar(x%10+'0');
11 }
12 int main(){
13     while(~scanf("%d%d%d",&n,&m,&k)){
14         memset(dp,0,sizeof(dp)),dp[0][0][0]=1LL;
15         for(int i=1;i<=k;++i){
16             memset(dp[i&1],0,sizeof(dp[i&1]));
17             for(int x=0;x<n;++x){
18                 for(int y=0;y<m;++y){
19                     for(int j=0;j<8;++j){
20                         nx=x+dir[j][0],ny=y+dir[j][1];
21                         if(nx>=0&&nx<n&&ny>=0&&ny<m)dp[i&1][nx][ny]=(dp[i&1][nx][ny]+dp[(i-1)&1][x][y])%mod;
22                     }
23                 }
24             }
25         }
26         print(dp[k&1][n-1][m-1]),puts("");
27     }
28     return 0;
29 }
View Code

递归:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn=220;
 5 const LL mod=1e9+7;
 6 int n,m,k,nx,ny,dir[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};LL dp[maxn][maxn][maxn];
 7 inline void print(LL x){
 8     if(x<0)putchar('-'),x=-x;
 9     if(x>9)print(x/10);
10     putchar(x%10+'0');
11 }
12 LL dfs(int step,int x,int y){
13     if(!step&&x==n-1&&y==m-1)return dp[step][x][y]=1;
14     if(step<=0)return 0;
15     if(dp[step][x][y]!=-1)return dp[step][x][y];
16     LL ans=0;
17     for(int i=0;i<8;++i){
18         int nx=x+dir[i][0],ny=y+dir[i][1];
19         if(nx>=0&&nx<n&&ny>=0&&ny<m)
20             ans=(ans+dfs(step-1,nx,ny)%mod)%mod;
21     }
22     return dp[step][x][y]=ans;
23 }
24 int main(){
25     while(~scanf("%d%d%d",&n,&m,&k)){
26         memset(dp,-1,sizeof(dp));
27         print(dfs(k,0,0)),puts("");
28     }
29     return 0;
30 }
View Code

G.小乐乐打游戏

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn=1005;
 5 int n,m,dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};char mp[maxn][maxn];
 6 int fx,fy,sx,sy,ex,ey,ans;bool vis[maxn][maxn];
 7 struct node{int x,y,step;}tmp,nod;
 8 queue<node> que;
 9 int bfs(int x,int y){
10     while(!que.empty())que.pop();
11     tmp.x=x,tmp.y=y,tmp.step=0;
12     que.push(tmp),vis[x][y]=true;
13     while(!que.empty()){
14         nod=que.front(),que.pop();
15         if(nod.x==ex&&nod.y==ey)return nod.step;
16         for(int i=0;i<4;++i){
17             int nx=nod.x+dir[i][0],ny=nod.y+dir[i][1];
18             if(nx>=0&&ny>=0&&nx<n&&ny<m&&!vis[nx][ny]&&mp[nx][ny]!='#'){
19                 vis[nx][ny]=true;
20                 tmp.x=nx,tmp.y=ny,tmp.step=nod.step+1;
21                 que.push(tmp);
22             }
23         }
24     }
25     return 0;
26 }
27 int main(){
28     while(cin>>n>>m){
29         for(int i=0;i<n;++i)cin>>mp[i];
30         for(int i=0;i<n;++i){
31             for(int j=0;j<m;++j){
32                 if(mp[i][j]=='S')sx=i,sy=j;
33                 else if(mp[i][j]=='F')fx=i,fy=j;
34                 else if(mp[i][j]=='E')ex=i,ey=j;
35             }
36         }
37         memset(vis,false,sizeof(vis));
38         ans=bfs(sx,sy);
39         if(ans&&ans<=abs(fx-ex)+abs(fy-ey))puts("PIG PIG PIG!");
40         else puts("A! WO SI LA!");
41     }
42     return 0;
43 }
View Code

H.留坑。

I.小乐乐学博弈:只要两堆石子的数量相等,小乐乐就一定会输。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a,b,k;
 4 int main(){
 5     while(cin>>a>>b>>k){
 6         if(a==b)puts("LAOZI CHUI SI NI!");
 7         else puts("HAI YOU SEI!");
 8     }
 9     return 0;
10 }
View Code

J.小乐乐和25:直接bfs模拟。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 int n,bits,m,t0,t1,t2,t3,t4;
 5 struct node{int x,step;}nod,tmp;
 6 map<int,bool> mp;queue<node> que;
 7 int bfs(int x){
 8     while(!que.empty())que.pop();
 9     nod.step=0,mp[nod.x=x]=true,que.push(nod);
10     while(!que.empty()){
11         nod=que.front(),que.pop();
12         if(nod.x%25==0)return nod.step;
13         for(int i=10,pos=2;pos<=bits;++pos,i*=10){
14             if(pos==bits)t0=0;
15             else t0=nod.x/(i*10)*(i*10);///前一位
16             t1=nod.x%i;
17             t2=t1/(i/10);
18             t1-=t2*(i/10);///后两位剩下的数字
19             t2*=i;///后一位
20             t3=nod.x/i%10*(i/10);///当前位
21             t4=t0+t1+t2+t3;
22             if(!mp[t4])mp[t4]=true,tmp.x=t4,tmp.step=nod.step+1,que.push(tmp);
23         }
24     }
25     return -1;
26 }
27 int main(){
28     while(cin>>n){
29         m=n,bits=0,mp.clear();
30         while(m)bits++,m/=10;
31         cout<<bfs(n)<<endl;
32     }
33     return 0;
34 }
View Code

 

posted @ 2018-12-05 23:37  霜雪千年  阅读(262)  评论(0编辑  收藏  举报