链接:https://codeforces.com/contest/2052/problem/E
题目:
思路:
一道模拟。重点在于:移动每个数字;判断是否成立。
问题一:选中每个数码,枚举需要移动到的位置,使用swap函数。
问题二:格式问题+算术问题。不能有前导0,不能两个非数字相连,同时位数不能超过十位,首位和末位不能是非数字。算术的话就前后判断是否一样就行。
但是我的代码不知道为什么一直RuntimeError。
源代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<map>
#include<string.h>
#include<string>
#include<vector>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
#define int long long
const int N = 1e3 + 10;
int aint[500], bint[500];bool isd(char x) { return x <= '9' and x >= '0'; }
string cal(string a, string b, string op)
{string ans ;int la = a.length(), lb = b.length();memset(aint, 0, sizeof(aint));memset(bint, 0, sizeof(bint));if (op == "+"){for (int i = 0; i < la; i++)aint[i] = a[la - 1 - i] - '0';for (int i = 0; i < lb; i++)bint[i] = b[lb - 1 - i] - '0';for (int i = 0; i < max(la,lb); i++){int ak = aint[i] + bint[i];ans = to_string(ak % 10)+ans;aint[i + 1] += ak / 10;}if (aint[max(la, lb)] or bint[max(la, lb)])ans = to_string((aint[max(la, lb)] + bint[max(la, lb)]) % 10) + ans;}else{if(la>lb){for (int i = 0; i < la; i++)aint[i] = a[la - 1 - i] - '0';for (int i = 0; i < lb; i++)bint[i] = b[lb - 1 - i] - '0';for (int i = 0; i < la; i++){int ak = aint[i] - bint[i];ans = to_string(ak % 10) + ans;if (ak < 0)aint[i + 1] += -1;}}else if(la==lb){for (int i = 0; i < la; i++)aint[i] = a[la - 1 - i] - '0';for (int i = 0; i < lb; i++)bint[i] = b[lb - 1 - i] - '0';for (int i = 0; i < la - 1; i++){int ak = aint[i] - bint[i];ans = to_string(ak % 10) + ans;if (ak < 0)aint[i + 1] += -1;}ans= to_string(abs(aint[la-1]-bint[lb-1])) + ans;if (aint[la-1] - bint[la-1] < 0)ans = '-' + ans;}else{swap(a, b); swap(la, lb);for (int i = 0; i < la; i++)aint[i] = a[la - 1 - i] - '0';for (int i = 0; i < lb; i++)bint[i] = b[lb - 1 - i] - '0';for (int i = 0; i < la; i++){int ak = aint[i] - bint[i];ans = to_string(ak % 10) + ans;if (ak < 0)aint[i + 1] += -1;}while (ans[0] == '0')ans = ans.substr(1, ans.length() - 1);ans = '-' + ans;}}while (ans[0] == '0')ans = ans.substr(1, ans.length() - 1);return ans;
}bool check(string k)
{string a[N];int id = 0;int eq = 0;int klen = k.length();for (int i = 0; i < klen; i++){if (!isd(k[i]) and k[i] != '.') { a[id] = k[i]; id++; continue; }int j = i + 1;for (j; j < klen; j++)if (!isd(k[j]) and k[j] != '.')break;a[id] = k.substr(i, j - i);i=j-1;id++;}for (int i = 0; i < id; i++)if (a[i] == "=")eq = i;if (!isd(a[0][0]) or !isd(a[eq+1][0]))return false;else{for (int i = 0; i < id; i++){if (a[i] == "+" or a[i] == "-")continue;string num = a[i];string inte, minn;int numlen = num.length();int minnlen = minn.size();int x = num.find('.');if (x == numlen - 1)return false;if (x == -1)inte = num;else if (x != numlen)inte = num.substr(0, x),minn = num.substr(x, num.length() - x);if (minnlen > 10)return false;if (numlen > 1 and num[0] == '0')return false;}string lef="0", righ="0";string op="+";for (int i = 0; i < eq; i++){if (a[i] == "+" or a[i] == "-") { op = a[i]; continue; }lef = cal(lef, a[i], op);}op = "+";for (int i = eq+1; i < id; i++){if (a[i] == "+" or a[i] == "-") { op = a[i]; continue; }righ = cal(righ, a[i], op);}return lef == righ;}}
signed main()
{IOS;string s; cin >> s;bool ans = check(s);string ansk=s;int slen = s.length();for (int i = 0; i < slen and !ans; i++){if (isd(s[i])){if (i == 0 )if(!isd(s[i + 1]))continue;else if (i == slen - 1 )if(!isd(s[i - 1]))continue;else{if(!isd(s[i - 1]) and !isd(s[i + 1]))continue;}for (int j = 0; j < slen - 1 and !ans; j++){string snew;if (i == j)continue;else{snew = s.substr(0, i) + s.substr(i + 1, slen - i - 1);snew = snew.substr(0, j) + s[i] + snew.substr(j, slen - j);}ans = check(snew);if (ans)ansk = snew;if (ans)break;}}}if (ans and ansk == s)cout <<"Correct";else if (ans) cout << ansk;else cout << "Impossible";return 0;
}
标程代码:
#include<bits/stdc++.h>
using namespace std;
const long long L=1e10;
// 表达式中数的上限(不超过 10 位)
inline bool check(string s){if(!isdigit(s[0]))return false;if(!isdigit(s.back()))return false;// 表达式头尾不能是符号for(int i=1;i<s.length();i++){if(s[i-1]=='0'){if(isdigit(s[i])&&(i==1||!isdigit(s[i-2])))return false;} // 特判“0d”的情况(其中 d 为一个数字)else if(!isdigit(s[i-1])){if(!isdigit(s[i]))return false;} // 特判其中某个数为空 / 等号两边有其他符号的情况}long long x=0,cl=0,cr=0;// 当前的数的绝对值、等号左边的值、等号右边的值int sgn=1; // 当前的数的符号bool f=false;for(char i:s){if(isdigit(i))x=x*10+i-'0';else{if(x>=L)return false;f?cr+=sgn*x:cl+=sgn*x;if(i=='=')f=true;x=0,sgn=i=='-'?-1:1;} // 遇到符号就处理当前的数}if(x>=L)return false;return cl==cr+sgn*x;
}
int main(){ios::sync_with_stdio(false);cin.tie(0); cout.tie(0);string s; cin>>s;if(check(s))cout<<"Correct\n",exit(0);for(int i=0;i<s.length();i++)if(isdigit(s[i])){string tl=s,tr=s;for(int j=i;j;j--){swap(tl[j],tl[j-1]);if(check(tl))cout<<tl<<endl,exit(0);} // 往左交换for(int j=i;j<s.length()-1;j++){swap(tr[j],tr[j+1]);if(check(tr))cout<<tr<<endl,exit(0);} // 往右交换}cout<<"Impossible\n"; // 无解情况return 0;
}