題目鏈接:https://nanti.jisuanke.com/t/44105
題意
題意就是給你一些四則運算的等式,等式的格式是 x op y = z,其中x,y,z都是字符串,表示某個進制下的數字,op是運算符,包括+,-,*,/。
現在有1~36進制可供選擇,你需要找到某個進制使得等式成立,輸出滿足等式的所有進制,找不到就輸出invalid。
其中,1~9進制用數字1-9表示,10~35進制用字母a-z表示,36進制用0來表示。注意,在等式中的0還是表示0,不是表示36。
同時,在任意進制下,等式中的三個數字轉換成十進制後必須在[1,232-1]區間內。
思路
題意也算比較好懂,基本上一看就知道是模擬,因爲實際上就是進制轉換(這剛學C語言就會做?),數據量也比較小。模擬也不見得就很好寫,有很多細節要注意。
- 在等式中的0還是表示0,不是表示36;在輸出進制時,若要表示爲36進制,則輸出0。
- 特判,要特別注意一進制! 本來一進制應該只包含0,但是題目規定一進制用1代替0,也就是說在本題中,一進制只能包含1,比如等式11 - 10 = 1,在一進制下就不成立,因爲10包含了0。
- inf=(1<<32)-1,這肯定是錯的,因爲1默認是int,1<<32直接爆int,所以要寫成(1ll<<32)-1。1ll等價於(long long)1,也就是必須要先把1強制轉換一下。
因爲第二點,wa了無數次,也是教訓。
爲什麼說在本題中,一進制只能包含1,看一下題目描述:
AC代碼
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=1e5+10,inf=(1ll<<32)-1;//記得寫1ll轉換成long long,這裏容易錯
ll T;
char a[N],b[N],c[N];
ll to_ll(char x)
{
if(x>='1'&&x<='9')return x-'0';
else if(x>='a'&&x<='z')return x-'a'+10;
else return 0;
}
ll to_char(ll x)
{
if(x>=1&&x<=9)return x+'0';
else if(x>=10&&x<=35)return x+'a'-10;
else return '0';
}
ll get_sum(char s[],ll bas)//將字符串轉換成bas進制下的數值
{
ll n=strlen(s);
ll ans=0;
ll tmp=1;
for(ll i=n-1;i>=0;i--)
{
if(tmp<0||tmp>inf||ans>inf||ans<0)return -1;
ll x=to_ll(s[i]);
//printf("x=%lld s[i]=%c\n",x,s[i]);
ans+=x*tmp;//tmp是bas的次方
tmp*=bas;
}
return ans;
}
ll get_mx(char s[])//得到字符串中最大的單個數字
{
ll n=strlen(s);
ll mx=0;
for(ll i=0;i<n;i++)
{
ll x=to_ll(s[i]);
mx=max(mx,x);
}
return mx;
}
bool have0(char s[])//判斷字符串中是否有0
{
for(int i=0;s[i];i++)
{
if(s[i]=='0')return 1;
}
return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin>>T;
while(T--)
{
char opt,dengyu;
cin>>a>>opt>>b>>dengyu>>c;
//printf("a=%s opt=%c b=%s dengyu=%c c=%s\n",a,opt,b,dengyu,c);
ll mx1=get_mx(a);
ll mx2=get_mx(b);
ll mx3=get_mx(c);
ll mx=max(max(mx1,mx2),mx3);
//printf("mx=%lld\n",mx);
if(opt=='+')
{
bool flag=0;
ll i;
for(mx==1?i=mx:i=mx+1;i<=36;i++)//遍歷可能的進制
{
ll s1=get_sum(a,i);
ll s2=get_sum(b,i);
ll s3=get_sum(c,i);
//printf("i=%lld %lld+%lld=%lld\n",i,s1,s2,s3);
if(!(s1>=1&&s1<=inf&&s2>=1&&s2<=inf&&s3>=1&&s3<=inf))continue;//滿足題目範圍
if(i==1&&(have0(a)||have0(b)||have0(c)))continue;//一進制不能包含0
if(s1+s2==s3)
{
flag=1;
printf("%c",to_char(i));
}
}
if(flag)printf("\n");
else printf("invalid\n");
}
else if(opt=='-')
{
bool flag=0;
ll i;
for(mx==1?i=mx:i=mx+1;i<=36;i++)
{
ll s1=get_sum(a,i);
ll s2=get_sum(b,i);
ll s3=get_sum(c,i);
if(!(s1>=1&&s1<=inf&&s2>=1&&s2<=inf&&s3>=1&&s3<=inf))continue;
if(i==1&&(have0(a)||have0(b)||have0(c)))continue;//一進制不能包含0
if(s1-s2==s3)
{
flag=1;
printf("%c",to_char(i));
}
}
if(flag)printf("\n");
else printf("invalid\n");
}
else if(opt=='*')
{
bool flag=0;
ll i;
for(mx==1?i=mx:i=mx+1;i<=36;i++)
{
ll s1=get_sum(a,i);
ll s2=get_sum(b,i);
ll s3=get_sum(c,i);
if(!(s1>=1&&s1<=inf&&s2>=1&&s2<=inf&&s3>=1&&s3<=inf))continue;
if(i==1&&(have0(a)||have0(b)||have0(c)))continue;//一進制不能包含0
if(s1*s2==s3)
{
flag=1;
printf("%c",to_char(i));
}
}
if(flag)printf("\n");
else printf("invalid\n");
}
else if(opt=='/')
{
bool flag=0;
ll i;
for(mx==1?i=mx:i=mx+1;i<=36;i++)
{
ll s1=get_sum(a,i);
ll s2=get_sum(b,i);
ll s3=get_sum(c,i);
if(!(s1>=1&&s1<=inf&&s2>=1&&s2<=inf&&s3>=1&&s3<=inf))continue;
if(i==1&&(have0(a)||have0(b)||have0(c)))continue;//一進制不能包含0
if(s1%s2==0&&s1/s2==s3)
{
flag=1;
printf("%c",to_char(i));
}
}
if(flag)printf("\n");
else printf("invalid\n");
}
}
return 0;
}
/*
1
11 - 10 = 1
ans:23456789abcdefghijklmnopqrstuvwxyz0
1
1 + 1 = 2
ans:3456789abcdefghijklmnopqrstuvwxyz0
*/