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;
}
posted @ 2024-12-23 17:42  WHUStar  阅读(3)  评论(0编辑  收藏  举报