- [NOIP2004 提高组] 虫食算
Help
- 2024-7-29 12:54:07 @
#include<bits/stdc++.h>
using namespace std;
string a1,a2,a3;
int n,ans[30],num[30],add[30];
bool vis[30];
bool flagb=false;
void dfs(int c,int row,int cnt){
if(flagb){
return;
}
if(cnt==n){
bool flag=true;
int nowadd=add[c];
for(int i=c;i>=0;i--){
int now=num[a1[i]]+num[a2[i]]+nowadd;
if(now%n!=num[a2[i]]){
return;
}
nowadd=now/n;
}
for(int i=0;i<n;i++){
ans[i]=num[i];
}
flag=true;
return;
}
if(c==-1){
flagb=true;
for(int i=0;i<n;i++){
ans[i]=num[i];
}
return;
}
for(int i=c-1;i>=0;i--){
int d0=num[a1[i]];
int d1=num[a2[i]];
int d2=num[a3[i]];
if(d0==-1||d1==-1||d2==-1){
continue;
}
if((d0+d1)%n!=d2&&(d0+d1+1)%n!=d2){
return;
}
}
if(row==2){
int now=num[a1[c]]+num[a2[c]]+num[a3[c]];
int d=now%n;
int s2c=a3[c];
if(num[s2c]==-1){
if(vis[d]){
return;
}
num[s2c]=d;
vis[d]=true;
add[c-1]=now/n;
dfs(c-1,0,cnt+1);
add[c-1]=0;
vis[d]=false;
num[s2c]=-1;
}
else{
if(d==num[s2c]){
add[c-1]=now/n;
dfs(c-1,0,cnt);
add[c-1]=0;
}
return;
}
}
int now;
if(row==0){
now=a1[c];
}
if(row==1){
now=a2[c];
}
if(row==2){
now=a3[c];
}
if(num[now]!=-1){
dfs(c,row+1,cnt);
return;
}
for(int i=0;i<n;i++){
if(!vis[i]){
num[now]=i;
vis[i]=true;
dfs(c,row+1,cnt+1);
if(flagb){
return;
}
num[now]=-1;
vis[i]=false;
}
}
}
int main(){
cin>>n>>a1>>a2>>a3;
for(int i=0;i<n;i++){
a1[i]-='A';
a2[i]-='A';
a3[i]-='A';
}
for(int i=0;i<n;i++){
num[i]=-1;
vis[i]=false;
}
dfs(n-1,0,0);
for(int i=0;i<n;i++){
cout<<ans[i]<<" ";
}
return 0;
}
啥也不是
2 条评论
-
jidingchen LV 7 (1090/1590) @ 2024-8-6 10:57:54
#include<bits/stdc++.h> using namespace std; long long n,l,r,mid; bool check(long long x) { return (x*log10(1.0*x)>=n); } int main() { cin>>n; n--; l=0,r=2000000000; while(l<r) { mid=(l+r)/2; if(check(mid)) r=mid; else l=mid+1; } cout<<l; }
-
2024-7-29 17:50:46@
#include <bits/stdc++.h> using namespace std; int n; string s[3]; // 现在来做第col列,从上往下第 row 个字符,之前已经确定了 cnt 个字符 int ans[30]; // 每个数字选了多少 int add[30]; // 每一列的进位 bool vis[30]; // 每个数字有没有被用过 void dfs(int col, int row, int cnt) { if (cnt == n) { bool flag = true; int nowAdd = add[col]; for (int i = col; i >= 0; i--) { int now = ans[s[0][i]] + ans[s[1][i]] + nowAdd; if (now % n != ans[s[2][i]]) return; nowAdd = now / n; } for (int i = 0; i < n; i++) cout << ans[i] << " "; exit(0); } // 根据目前确定的数字,检查每一列是否合法 for (int i = col - 1; i >= 0; i--) { int d0 = ans[s[0][i]]; int d1 = ans[s[1][i]]; int d2 = ans[s[2][i]]; if (d0 == -1 || d1 == -1 || d2 == -1) continue; if ((d0 + d1) % n != d2 && (d0 + d1 + 1) % n != d2) return; } if (row == 2) { // 上面两个数之和加上进位的结果 int now = ans[s[0][col]] + ans[s[1][col]] + add[col]; // 当前位置应该是 d int d = now % n; // 当前位置的字母为 s2col int s2col = s[2][col]; if (ans[s2col] == -1) { // 之前没有确定下来的当前位置的值 if (vis[d]) return; // 如果 d 被别的字母用过了,肯定非法 // 如果d没有被用过,那就分配给当前位置用 ans[s2col] = d; vis[d] = true; add[col - 1] = now / n; // 标记一下更高位需要进位的值 dfs(col - 1, 0, cnt + 1); // 当前列处理完了,往更高位的列去处理 // 撤销前面施加的影响 add[col - 1] = 0; vis[d] = false; ans[s2col] = -1; } else { // 之前已经确定过了的当前位置的值 if (d == ans[s2col]) { // 合法时可以继续往后做 add[col - 1] = now / n; dfs(col - 1, 0, cnt); add[col - 1] = 0; } } return; } //========================= // 考虑当前位置的选择 int now = s[row][col]; // 当前位置字母对应的 0~25 的数字 // 如果当前位置的值之前已经确定了 if (ans[now] != -1) { dfs(col, row + 1, cnt); // 看下一个位置 return; } // 如果当前位置的值之前没确定,枚举所有可能性 for (int i = 0; i < n; i++) { if (!vis[i]) { // now 这个字母选择 i 来替换 ans[now] = i; vis[i] = true; dfs(col, row + 1, cnt + 1); // 撤销对应的影响 ans[now] = -1; vis[i] = false; } } }
int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n; cin >> s[0]; cin >> s[1]; cin >> s[2]; for (int i = 0; i < n; i++) { s[0][i] -= 'A'; s[1][i] -= 'A'; s[2][i] -= 'A'; } for (int i = 0; i < n; i++) { ans[i] = -1; vis[i] = false; } // 从第 n-1 列,第 0 行的位置,开始枚举 // 目前已经确定了 0 个数的值 dfs(n - 1, 0, 0); return 0; }
- 1
信息
- ID
- 93
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 161
- 已通过
- 40
- 上传者