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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
AtCoder Beginner Contest 134 是一场 AtCoder 的入门级比赛,以下是每道题的简要题解: A - Dodecagon 题目描述:已知一个正十二边形的边长,求它的面积。 解题思路:正十二边形的内角为 $150^\circ$,因此可以将正十二边形拆分为 12 个等腰三角形,通过三角形面积公式计算面积即可。 B - Golden Apple 题目描述:有 $N$ 个苹果和 $D$ 个盘子,每个盘子最多可以装下 $2D+1$ 个苹果,求最少需要多少个盘子才能装下所有的苹果。 解题思路:每个盘子最多可以装下 $2D+1$ 个苹果,因此可以将苹果平均分配到每个盘子中,可以得到最少需要 $\lceil \frac{N}{2D+1} \rceil$ 个盘子。 C - Exception Handling 题目描述:给定一个长度为 $N$ 的整数序列 $a$,求除了第 $i$ 个数以外的最大值。 解题思路:可以使用两个变量 $m_1$ 和 $m_2$ 分别记录最大值和次大值。遍历整个序列,当当前数不是第 $i$ 个数时,更新最大值和次大值。因此,最后的结果应该是 $m_1$ 或 $m_2$ 中较小的一个。 D - Preparing Boxes 题目描述:有 $N$ 个盒子和 $M$ 个物品,第 $i$ 个盒子可以放入 $a_i$ 个物品,每个物品只能放在一个盒子中。现在需要将所有的物品放入盒子中,每次操作可以将一个盒子内的物品全部取出并分配到其他盒子中,求最少需要多少次操作才能完成任务。 解题思路:首先可以计算出所有盒子中物品的总数 $S$,然后判断是否存在一个盒子的物品数量大于 $\lceil \frac{S}{2} \rceil$,如果存在,则无法完成任务。否则,可以用贪心的思想,每次从物品数量最多的盒子中取出一个物品,放入物品数量最少的盒子中。因为每次操作都会使得物品数量最多的盒子的物品数量减少,而物品数量最少的盒子的物品数量不变或增加,因此这种贪心策略可以保证最少需要的操作次数最小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力的老周

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

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

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

打赏作者

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

抵扣说明:

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

余额充值