ABC 161部分题解

Part 1 题解

[ABC161A]ABC Swap

思路: 模拟

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

int a,b,c;

signed main()
{
	cin>>a>>b>>c;
	swap(a,b);
	swap(a,c);
	cout<<a<<' '<<b<<' '<<c<<endl;
	
	return 0;
}

[ABC161B]Popular Vote

思路: 模拟+简单计数。注意用double存储一些变量,否则容易WA。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

double n,m,sumv,ans=0;
double a[100005];

signed main()
{
	cin>>n>>m;
	for (int i=1;i<=n;i++)
	{
		cin>>a[i];
		sumv+=a[i];
	}
	double num=sumv*(1.00/(4.00*m));
	
	for (int i=1;i<=n;i++)
	{
		if (a[i]>=num)  ans++;
	}
	if (ans>=m)  cout<<"Yes"<<endl;
	else cout<<"No"<<endl;
	
	return 0;
}

[ABC161C]Replacing Integer

思路:

题面事实上就是让你构造一个 s s ,使得 n s k |n-sk| 的值最小。易知答案为 n n % k k k k - n n % k k

所以直接输出上述两者的较大值即可。时间复杂度 O ( 1 ) O(1)

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,k;

signed main()
{
	cin>>n>>k;
	cout<<min(n%k,k-(n%k))<<endl;
	
	return 0; 
}

[ABC161D]Lunlun Number

前言:

什么?这是数学题?对不起,阁下想得太复杂了。

这是一道枚举题!

思路

考虑将答案从第一个 L u n l u n Lunlun 数开始变换 n 1 n-1 次,"变换"定义为将该 L u n l u n Lunlun 数变成下一个 L u n l u n Lunlun 数。

"变换"的函数怎么搞呢? 举三个例子:

①变换 223 223 。容易发现第 2 2 2 2 可以变换,就把第 2 2 2 2 变成 3 3 ;然后后面每位的值全部变成 m a x max (前一位的值 1 -1 , 0 0 )。所以223变成了232.

②变换 123 123 。发现可以将1变换,即将1变成2;然后后面每位的值全部变成 m a x max (前一位的值 1 -1 , 0 0 )。所以 123 123 变成了 210 210 .

③变换 999 999 。既然三位都变换不了,那么就直接位数++,把 999 999 变成 1000 1000 .

模拟即可。时间复杂度: O ( n ) O(n) (常数不大, d o n t don't w o r r y worry )。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

int k,head=99;
int a[105];

inline void change()//存在了head-100 
{
	int j=101;
	for (int k=j-1;k>=head+1;k--)
	{
		if (a[k]!=a[k-1]+1&&a[k]!=9)
		{
			j=k;
			break;
		}
	}
	if (j!=101)
	{
		a[j]++;
		for (int k=j+1;k<=100;k++)
		{
			if (a[k-1]-1>=0)  a[k]=a[k-1]-1;
			else a[k]=a[k-1];
		}
		return;
	}
	if (j==101&&a[head]!=9)
	{
		a[head]++;
		for (int k=head+1;k<=100;k++)
		{
			if (a[k-1]-1>=0)  a[k]=a[k-1]-1;
			else a[k]=a[k-1];
		}
		return;
	}
	else if (a[head]==9&&j==101)
	{
		head--;
		a[head]=1;
		for (int k=head+1;k<=100;k++)  a[k]=0;
	}
}

signed main()
{
	cin>>k;
		
	if (k<=9)  return cout<<k<<endl,0;
	k-=10;
	a[head]=1,a[head+1]=0;
	
	for (int i=1;i<=k;i++)  change();
	for (int i=head;i<=100;i++)  cout<<a[i];
	
	return 0; 
}

[ABC161F]Division or Substraction

前言:

本题在比赛后AC······如果比赛时脑子没瓦特也能AC的

这一次比赛明显E题比F题难得多啊。

思路:

首先容易知道,如果k(k≠1)满足要求,那么一定存在①k|n或②k|n-1。解释一下:

①如果k|n,那么刚开始n就变成了n/k;所以有可能可以;

②如果k|n-1,那么就一定不存在k|n;所以n将会不停地减去k,最终得到1.

所以只需要枚举这样的k(为n的约数或n-1的约数)并判断一下就行啦。

卡点:

①要快速判断k是否满足要求: 当k不是n的约数时就直接讲n变成n%k而不是不停地减;

②注意要将答案去重;最好的方法就是用一个map存下答案,最后输出map的长度就可以啦;

③如果你看到了数据范围,就开long long

上代码, 咕咕咕 ~

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n,ans=0;

map<int,bool> visited;
map<int,bool>::iterator it;

inline void get(int x)
{
	if (x==1)  return;
	
	int m=n;
	while (m%x==0)  m/=x;
	if (m%x==1) 
	{
		if (!visited[x])  visited[x]=1;
	}
}

signed main()
{
	cin>>n;
	for (int i=1;i*i<=n;i++)
	{
		if (n%i==0)  get(i),get(n/i);
	}
	for (int i=1;i*i<=n-1;i++)
	{
		if ((n-1)%i==0)  get(i),get((n-1)/i);
	}
	for (it=visited.begin();it!=visited.end();it++)  ans++;
	cout<<ans<<endl;
	
	return 0;
}

Part 2 总结

①比赛中得分: 1000
②比赛后得分: 1600

在这里插入图片描述

③排名: 1610

④总结: 没什么好说的了,就是得到了一个教训:

谁说后面的题总是比前面的题难?!

原创文章 19 获赞 27 访问量 1953

猜你喜欢

转载自blog.csdn.net/Cherrt/article/details/105318014
ABC