E. Expression Correction
链接: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;
}