2 条题解
-
5
一道恶心的大模拟,一定要分步做
1、枚举“有效区域”
题目要求是四个顶点字母恰好和原始数字表的四个顶点数字互相对应,即 与 对应、 与 对应、 与 对应、 与 对应
2、记录每次解密
每次找到一个“有效区域”,我们就要统计它四角的大写字母个数,以便后面的旋转
3、顺时针旋转
这个式子要自己推理,代码如下:
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) turn[i][j]=s[n-j+1][i];
4、进行“数字关联”
考虑建立01数组,对于 数组,若 { } ,则标记为 ,反之同理(注意特判 的情况);若 为大写字母,则标记为 ,反之同理,若 的标记等于 的标记,或者 ,则数字关联成功,给答案字符串加上这个字符
实现以上功能后输出即可。
屎山展示:
#include<bits/stdc++.h> using namespace std; int n,m,s[305][305],cun[305][305],a[305][305],dx[305][305],turn[305][305]; char num[305][305],alp[305][305]; string ans=""; int check(int u){ return int(u==2||u==3||u==5||u==7); } int main(){ cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>num[i][j]; s[i][j]=int(num[i][j]-'0'); cun[i][j]=s[i][j]; } } for(int i=1;i<=m;i++){ for(int j=1;j<=m;j++){ cin>>alp[i][j]; if(alp[i][j]>='a'&&alp[i][j]<='z') a[i][j]=int(alp[i][j]-'a')+1,dx[i][j]=0; else a[i][j]=int(alp[i][j]-'A')+1,dx[i][j]=1; } } for(int i=1;i<=m-n+1;i++){ for(int j=1;j<=m-n+1;j++){ int cnt=0; if(a[i][j]==s[1][1]&&a[i+n-1][j]==s[n][1]&&s[1][n]==a[i][j+n-1]&&s[n][n]==a[i+n-1][j+n-1]){ if(alp[i][j]<'a') cnt++; if(alp[i+n-1][j]<'a') cnt++; if(alp[i][j+n-1]<'a') cnt++; if(alp[i+n-1][j+n-1]<'a') cnt++; for(int x=i;x<=i+n-1;x++) for(int y=j;y<=j+n-1;y++) if((check(s[x-i+1][y-j+1])==dx[x][y]&&s[x-i+1][y-j+1]!=1)||s[x-i+1][y-j+1]==0) ans+=alp[x][y]; for(int p=1;p<=cnt;p++){ for(int x=1;x<=n;x++) for(int y=1;y<=n;y++) turn[x][y]=s[n-y+1][x]; for(int x=1;x<=n;x++) for(int y=1;y<=n;y++) s[x][y]=turn[x][y]; for(int x=i;x<=i+n-1;x++) for(int y=j;y<=j+n-1;y++) if((check(s[x-i+1][y-j+1])==dx[x][y]&&s[x-i+1][y-j+1]!=1)||s[x-i+1][y-j+1]==0) ans+=alp[x][y]; } for(int x=1;x<=n;x++) for(int y=1;y<=n;y++) s[x][y]=cun[x][y]; } } } if(ans=="") cout<<"No solution"; else cout<<ans; }
信息
- ID
- 768
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- (无)
- 递交数
- 67
- 已通过
- 12
- 上传者