第一次很顺畅地AK呢,发篇题解纪念一下。
A
思路
直接扫一遍,如果该位上不是 ,那么它就一定是一个Round Number的首位。然后根据位值原理,后面填 就可以啦。
如 中的 代表的是 个 ,那么一个Round Number就是 。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main()
{
int t;
cin>>t;
while (t--)
{
int pos=1,cnt=0,ans[10];
string s;
cin>>s;
for (int i=s.size()-1;i>=0;i--)
{
if (s[i]!='0') ans[++cnt]=(s[i]-'0')*pos;
pos*=10;
}
cout<<cnt<<endl;
for (int i=1;i<=cnt;i++) cout<<ans[i]<<' ';
cout<<endl;
}
return 0;
}
难度: 入门
B
思路
个人认为本题的正解与数论没个P关系。
直接看它能否拆成几个奇数或者几个偶数之和。我们定义两个数组 , 尝试了奇数的拆分, 尝试了偶数的拆分。
那么,对于所有的 的正整数 ,均将 赋为1, 赋为2(注意输出的所有数必须都是正整数,所以 不能赋为0),然后算一算 与 就可以啦。
如果
且
为奇数,那么就输出Yes与数组
。
如果$
且
为偶数,那么久输出Yes与数组
。
如果发现前者与后者均不满足,那么就直接打印 。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,n,k;
signed main()
{
cin>>t;
while (t--)
{
int a[105]={0},b[105]={0};
cin>>n>>k;
if (n<k)
{
cout<<"NO"<<endl;
continue;
}
for (int i=1;i<=k-1;i++) a[i]=1,b[i]=2;
a[k]=n-(k-1);
b[k]=n-2*(k-1);
if (a[k]%2==1&&a[k]>0)
{
cout<<"YES"<<endl;
for (int i=1;i<=k;i++) cout<<a[i]<<' ';
}
else if (b[k]%2==0&&b[k]>0)
{
cout<<"YES"<<endl;
for (int i=1;i<=k;i++) cout<<b[i]<<' ';
}
else cout<<"NO";
cout<<endl;
}
return 0;
}
难度: 普及-
C
怎么全是小学奥数题啊
首先在草稿纸上尝试找到规律。
规律显然,然后用周期问题搞一搞就可以啦。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,n,k;
signed main()
{
cin>>t;
while (t--)
{
int pos=0;
cin>>n>>k;//4 12
pos+=(k/(n-1))*n;//16
if (k%(n-1)==0) pos--;//找到上一个周期的末位
int now=k%(n-1);//加上剩下的一部分
if (now<n) pos+=now;
else pos+=(now+1);
cout<<pos<<endl;
}
return 0;
}
难度: 普及-
D
思路
按照题意模拟即可,但是有些考验代码能力与心态 (TM调试得累死了)
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,n;
int a[200005];
signed main()
{
cin>>t;
while (t--)
{
cin>>n;
for (int i=1;i<=n;i++) cin>>a[i];
int head=0,tail=n+1,cnt=0,alice=0,bob=0,last=0;
while (head+1<tail)
{
cnt++;
if (cnt%2==1)
{
int sumv=0;
for (int i=head+1;i<tail;i++)
{
sumv+=a[i];
if (sumv>last)
{
head=i;
break;
}
}
alice+=sumv;
if (sumv<=last) break;
last=sumv;
}
else if (cnt%2==0)
{
int sumv=0;
for (int i=tail-1;i>head;i--)
{
sumv+=a[i];
if (sumv>last)
{
tail=i;
break;
}
}
bob+=sumv;
if (sumv<=last) break;
last=sumv;
}
}
cout<<cnt<<' '<<alice<<' '<<bob<<endl;
}
return 0;
}
难度: 普及-
E
思路
首先,看到 的限制与 的限制,告诉我们正解应该是一个常数小的 算法。但是,空间限制只有 ,说明我们必须摒弃大空间写法。
于是,我开始考虑,先用 的代价找到, 中的每个数是否能够成为一个长度不小于2的区间内各数之和。最后扫一遍,数一数这样的 即可。
但是怎么用仅仅 且小空间的方法来找到所有 的值呢?
首先,定义一个 数组,其中 表示 能否成为 的值。
①不需要大空间。虽然一个区间的和可能会达到 ,但是所有的数均不大于 ,也就意味着所有 的值均不大于 。所以 数组的大小开到 就可以啦。
②我们枚举 ,然后找 。用一个 来计算目前 的值,只要 超过了 就立刻跳出( )。对于所有满足要求的 ,将 的值赋为1。
最后扫一遍,看看 是否为1就知道它是否为 啦。数一数即可。
时间复杂度: ( )
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,n,a[10005];
signed main()
{
cin>>t;
while (t--)
{
int tot=0,ans=0;
bool visited[10005]={0};
cin>>n;
for (int i=1;i<=n;i++) cin>>a[i];
for (int i=1;i<=n-1;i++)
{
int sumv=a[i];
for (int j=i+1;j<=n;j++)
{
sumv+=a[j];
if (sumv>n) break;
else visited[sumv]=1;
}
}
for (int i=1;i<=n;i++)
{
if (visited[a[i]]==1) ans++;
}
cout<<ans<<endl;
}
return 0;
}
难度: 普及/提高-
F
思路
先凑 个 ,再弄 个 ;然后随便搞一搞弄出 个相邻且不同的位置即可。
注意 个1与 个0之间有一个交界处,那么 就应该减去1。然后从 开始构造,每个数均为上一个数加上1模2的值(相当于0后1,1后0)。
题目保证有解!
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,a,b,c;
int s[1005];
signed main()
{
cin>>t;
while (t--)
{
int pos=0;
cin>>a>>b>>c;//0 4 0
if (a!=0)
{
for (int i=pos+1;i<=pos+a+1;i++) s[i]=0;
pos+=(a+1);
}
if (c!=0)
{
for (int i=pos+1;i<=pos+c+1;i++) s[i]=1;
pos+=(c+1);
}
if (b!=0)
{
if (a==0||b==0)
{
for (int i=pos+1;i<=pos+b+1;i++) s[i]=(s[i-1]+1)%2;
pos+=(b+1);
}
else
{
for (int i=pos+1;i<=pos+b;i++) s[i]=(s[i-1]+1)%2;
pos+=b;
}
}
for (int i=1;i<=a+b+c+1;i++) cout<<s[i];
cout<<endl;
}
return 0;
}
难度: 普及/提高-
G
思路
如果 为1或2或3,直接输出-1。
如果 为奇数,则这么构造:
①
时,
②
时,
如果 为偶数,则这么构造:
①
时,
②
时,
如果您并不会做这一题,建议您找一下上面我构造的数组的规律。
然后上惨不忍睹的代码~
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t,n;
int a[1005];
signed main()
{
cin>>t;
while (t--)
{
cin>>n;
if (n==1||n==2||n==3)
{
cout<<"-1"<<endl;
continue;
}
if (n%2==0)
{
for (int i=1;i<=(n/2);i++) a[i]=i*2;
a[(n/2)+1]=a[(n/2)]-3;
a[(n/2)+2]=a[(n/2)+1]+2;
for (int i=(n/2)+3;i<=n;i++)
{
a[i]=a[i-1]-2;
if (a[i]==a[(n/2)+1]||a[i]==a[(n/2)+2]) a[i]-=2;
}
}
else if (n%2==1)
{
for (int i=1;i<=(n/2)+1;i++) a[i]=i*2-1;
a[(n/2)+2]=a[(n/2)+1]-3;
a[(n/2)+3]=a[(n/2)+2]+2;
for (int i=(n/2)+4;i<=n;i++)
{
a[i]=a[i-1]-2;
if (a[i]==a[(n/2)+2]||a[i]==a[(n/2)+3]) a[i]-=2;
}
}
for (int i=1;i<=n;i++) cout<<a[i]<<' ';
cout<<endl;
}
return 0;
}
难度: 普及/提高-
Summary
①本蒟蒻的做题信息:
编号 | 做题时间 | UnAC次数 |
---|---|---|
A | 4min | 0 |
B | 9min | 0 |
C | 11min | 0 |
D | 26min | 0 |
E | 17min | 0 |
F | 35min | 4 |
G | 24min | 1 |
②排名: 1320
赶紧膜拜班里一位比我强太多,早就 的神犇。
③总结
做这种水题不能再这么慢了,总是失误——如果这是NOIP的话,我只能AC五题(只有一次提交机会啊)。
我还是太弱了~
撒花✿✿ヽ(°▽°)ノ✿撒花