AtCoder Beginner Contest 192 简单题解(AC了 A~D,缺 E~F)

ABC192

https://atcoder.jp/contests/abc192/tasks

A题:Star

题目链接,https://atcoder.jp/contests/abc192/tasks/abc192_a

题解

友善签到题。一个简单的数学题。获得 ans=X%100 余数,如果 ans 为零,则输出 100;否则输出 100-ans。

AC 参考代码

    #include <bits/stdc++.h>
     
    using namespace std;
     
    //如果提交到OJ,不要定义 __LOCAL
    //#define __LOCAL
     
    int main() {
    #ifndef __LOCAL
    	//这部分代码需要提交到OJ,本地调试不使用
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    #endif
    	int x;
    	cin>>x;
    	int ans;
    	if (0==x%100) {
    		ans=100;
    	} else {
    		ans=100-x%100;
    	}
    	cout<<ans<<"\n";
     
    #ifdef __LOCAL
    	//这部分代码不需要提交到OJ,本地调试使用
    	system("pause");
    #endif
    	return 0;
    }

B题:uNrEaDaBlE sTrInG

题目链接,https://atcoder.jp/contests/abc192/tasks/abc192_b

题解

直接字符判断是否符合题意即可。如果用 string 的话,要注意奇偶性和题目描述相反。

AC 参考代码

    #include <bits/stdc++.h>
     
    using namespace std;
     
    //如果提交到OJ,不要定义 __LOCAL
    //#define __LOCAL
     
    int main() {
    #ifndef __LOCAL
    	//这部分代码需要提交到OJ,本地调试不使用
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    #endif
    	string s;
    	cin>>s;
    	for (int i=0; i<s.length(); i++) {
    		if (0==i%2) {
    			if (s[i]>='A'&&s[i]<='Z') {
    				cout<<"No\n";
    				return 0;
    			}
    		} else {
    			if (s[i]>='a'&&s[i]<='z') {
    				cout<<"No\n";
    				return 0;
    			}
    		}
    	}
    	cout<<"Yes\n";
     
    #ifdef __LOCAL
    	//这部分代码不需要提交到OJ,本地调试使用
    	system("pause");
    #endif
    	return 0;
    }

C题:Kaprekar Number

题目链接:https://atcoder.jp/contests/abc192/tasks/abc192_c

题解

没想到好办法,直接当模拟题。就是实现了 g1() 和 g2() 函数。

AC 参考代码

    #include <bits/stdc++.h>
     
    using namespace std;
     
    //如果提交到OJ,不要定义 __LOCAL
    //#define __LOCAL
     
    typedef long long ll;
     
    int a[20];
    int len;
    ll g1() {
    	sort(a+1, a+len, greater<int>());
    	ll ans=0;
    	for (int i=1; i<len; i++) {
    		ans=ans*10+a[i];
    	}
    	return ans;
    }
     
    ll g2() {
    	sort(a+1, a+len, less<int>());
    	ll ans=0;
    	for (int i=1; i<len; i++) {
    		ans=ans*10+a[i];
    	}
    	return ans;
    }
     
    const int MAXK=1e5+4;
    int b[MAXK];
     
    int main() {
    #ifndef __LOCAL
    	//这部分代码需要提交到OJ,本地调试不使用
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    #endif
    	ll n,k;
    	cin>>n>>k;
     
    	b[0]=n;
    	for (int i=1; i<=k; i++) {
    		len=1;
    		n=b[i-1];
    		while (n) {
    			a[len]=n%10;
    			n/=10;
    			len++;
    		}
     
    		b[i]=g1()-g2();
    		if (0==b[i]) {
    			cout<<"0\n";
    			return 0;
    		}
    	}
     
    	cout<<b[k]<<"\n";
     
    #ifdef __LOCAL
    	//这部分代码不需要提交到OJ,本地调试使用
    	system("pause");
    #endif
    	return 0;
    }

时间复杂度

O(K*9*log9)\approx O(K)

D题:Base n

题目链接,https://atcoder.jp/contests/abc192/tasks/abc192_d

题解

二分答案。有人问为什么可以二分查找答案,下面写一个简单的回答。

题目意思是给你一个字符串 X 和数字 M,问有几个 n 进制可能,对应的数据小于 M。我们假设给一个字符串 123,M=50,下面我们来看一下数据变化。首先我们知道这样不能是二进制、三进制。

(123)_{4}=1*4^2+2*4^1+3*4^0=16+8+3=(27)_{10}\\ (123)_{5}=1*5^2+2*5^1+3*5^0=25+10+3=(38)_{10}\\ (123)_{6}=1*6^2+2*6^1+3*6^0=36+12+3=(40)_{10}\\ (123)_{7}=1*7^2+2*7^1+3*7^0=49+14+3=(66)_{10}\\

由于 66>50,所以我们就不需要向上继续走了,这样我们可以得到对应的答案是 6-4=2。从上面的公式我们可以看出,123 的 B 进制对应的计算方法为:1*B^2+2*B^1+3*B^0,由于进制都是正数,因此这个公式是一个单调递增的,所以我们可以用二分来查找答案。

AC 参考代码

#include <bits/stdc++.h>

using namespace std;

//如果提交到OJ,不要定义 __LOCAL
#define __LOCAL

typedef long long ll;

string s;
ll m;

bool mul(ll &x, ll y) {
	ll t=0;
	while (y) {
		if (x>m) {
			return false;
		}
		if (y&1) {
			t+=x;
		}
		x+=x;
		y>>=1;
		if (t>m) {
			return false;
		}
	}
	x=t;
	return true;
}

bool check(ll bs) {
	ll now=0;
	for (int i=0; s[i]; i++) {
		int bt=s[i]-'0';
		bool ok=mul(now, bs);
		now += bt;
		if (false==ok || now>m) {
			return false;
		}
	}
	return true;
}
int main() {
#ifndef __LOCAL
	//这部分代码需要提交到OJ,本地调试不使用
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
#endif
	cin>>s>>m;

	//找x得最大值
	int mx=0;
	for (int i=0; i<s.length(); i++) {
		mx=max(mx, s[i]-'0');
	}
	mx++;

	//特判
	if (1==s.length()) {
		if (s[0]-'0'<=m) {
			cout<<"1\n";
		} else {
			cout<<"0\n";
		}
		return 0;
	}

	if (false==check(mx)) {
		cout<<"0\n";
	} else {
		//二分
		ll l=mx, r=1e18, ans;
		while (l<=r) {
			ll mid=(l+r)>>1;
			if (check(mid)) {
				ans=mid;
				l=mid+1;
			} else {
				r=mid-1;
			}
		}
		cout<<ans-mx+1<<"\n";
	}

#ifdef __LOCAL
	//这部分代码不需要提交到OJ,本地调试使用
	system("pause");
#endif
	return 0;
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的老周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值