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 s,使得 ∣ n − s k ∣ |n-sk| ∣n−sk∣的值最小。易知答案为 n n n% k k k或 k k k- n n n% k k k。
所以直接输出上述两者的较大值即可。时间复杂度 O ( 1 ) 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 Lunlun数开始变换 n − 1 n-1 n−1次,"变换"定义为将该 L u n l u n Lunlun Lunlun数变成下一个 L u n l u n Lunlun Lunlun数。
"变换"的函数怎么搞呢? 举三个例子:
①变换 223 223 223。容易发现第 2 2 2个 2 2 2可以变换,就把第 2 2 2个 2 2 2变成 3 3 3;然后后面每位的值全部变成 m a x max max(前一位的值 − 1 -1 −1, 0 0 0)。所以223变成了232.
②变换 123 123 123。发现可以将1变换,即将1变成2;然后后面每位的值全部变成 m a x max max(前一位的值 − 1 -1 −1, 0 0 0)。所以 123 123 123变成了 210 210 210.
③变换 999 999 999。既然三位都变换不了,那么就直接位数++,把 999 999 999变成 1000 1000 1000.
模拟即可。时间复杂度: O ( n ) O(n) O(n) (常数不大, d o n ′ t don't don′t w o r r y worry 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
④总结: 没什么好说的了,就是得到了一个教训: