唯一一场每道题都有思路的比赛,感觉还行,虽然有思路不代表能AC,不过还是很开心的,因为除了E题的桶没想到外其他都是自力更生做出来的😊

A Sum of Round Numbers

分析

签到题,就是遍历数的每一位,求出非0的位数有几位,然后int一个v=1,之后没走一个数v*=10,然后当一位数不等于0时就乘上v就行了,这道题用字符串应该更简单,但是我想试试用while,练练手

CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#define ios ios::sync_with_stdio(0)
using namespace std;
const int MAXN=1e4+100;
int main()
{
ios;
int t,k;
cin>>t;
while(t--){
cin>>k;
int cnt=0,x=k,v=1;
while(k/10){
int tt=k%10;
if(tt!=0) cnt++;
k/=10;
}
cout<<cnt+1<<endl;
while(x/10){
int tt=x%10;
if(x/10&&tt!=0) cout<<tt*v<<" ";
x/=10; v*=10;
}
cout<<(x%10)*v<<endl;
}
return 0;
}

B - Same Parity Summands

分析

这道题是给你一个a和b,让你用b个同为偶数或者奇数的数加起来等于a,输出这些数,刚开始我一直在找规律,感觉很麻烦,找了半小时也没涵盖所有情况,后来发现直接暴力枚举就行了,我们可以考虑极端,当都为奇数时,让除了最后一个数以外的数都是1,然后最后一个数=a-(b-1),加起来正好等于a,同理都为偶数时,让除了最后一个数以外的数全部变成2,最后一个数为n-2*(k-1),条件都不符合输出NO想通这个就AC了

CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#define ios ios::sync_with_stdio(0)
using namespace std;
const int MAXN=1e4+100;
int main()
{
ios;
int t,k,n;
cin>>t;
while(t--){
cin>>n>>k;
int m=n-(k-1);
if(m>0&&m%2){
cout<<"YES"<<endl;
for(int i=0;i<k-1;i++){
cout<<1<<" ";
}
cout<<m<<endl;
continue;
}
m=n-2*(k-1);
if(m>0&&m%2==0){
cout<<"YES"<<endl;
for(int i=0;i<k-1;i++){
cout<<2<<" ";
}
cout<<m<<endl;
continue;
}
cout<<"NO"<<endl;


}
return 0;
}

C - K-th Not Divisible by n

分析

看题目就知道大意,不被n整除的第K个数,首先我们清楚被N整除的数之间的数数量一定是相同的,比如能整除8的:8 16 24…数之间都相差8,那这就是一个找规律嘛,用“%”找到该数在一段区间的那个位置,然后用“/”找到在第几个区间就行了

CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#define ios ios::sync_with_stdio(0)
using namespace std;
const int MAXN=1e4+100;
int main()
{
ios;
int t,k,n;
cin>>t;
while(t--){
int a,b;
cin>>a>>b;
int k=b%(a-1);
if(k==0){
cout<<(b/(a-1)*a)-1<<endl;
}
else cout<<(b/(a-1)*a)+k<<endl;
}
return 0;
}

D. Alice, Bob and Candies

分析

这道题好长啊,我第一眼就被吓住了,不战而屈人之兵,不过狠下心来读一读,发现就是一个双向指针往中间合拢,好像这叫双向队列~~,再多定义几个变量记录每次每个人吃多少,每个人上次吃了多少,就是一个模拟,只要能写对条件,就能AC了

CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#define ios ios::sync_with_stdio(0)
using namespace std;
const int MAXN=1e4;
int val[MAXN];
int main()
{
ios;
int t; cin>>t;
while(t--){
int n,pa=0,pb=0,flg=0;; cin>>n;
int sum=0;
for(int i=1;i<=n;i++){
cin>>val[i];
sum+=val[i];
}
int ea=0,eb=0,cnt=1,sa,sb,head=1,tail=n;
while(tail-head>=0){
sa=0; sb=0;
if(flg==0&&sum-ea-eb>pb){
while(sa<=pb){
sa+=val[head];
ea+=val[head];
head++;
}
pa=sa; flg=1; cnt++;
continue;
}
if(flg==1&&sum-ea-eb>pa){
while(sb<=pa){
sb+=val[tail];
eb+=val[tail];
tail--;
}
pb=sb; flg=0; cnt++;
continue;
}
cnt++;
if(flg==0){
ea+=sum-ea-eb;
break;
}else{
eb+=sum-ea-eb;
break;
}
}
cout<<cnt-1<<" "<<ea<<" "<<eb<<" "<<endl;
}
return 0;
}
双向队列超级简单,水题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
deque<int> dq;
int main()
{
int t;
cin>>t;
while(t--){
dq.clear();
int n; cin>>n;
for(int i=1;i<=n;i++){
int temp; cin>>temp;
dq.push_back(temp);
}
ll pa=0,pb=0,suma=0,sumb=0,res=1,ansa=0,ansb=0,cnt=0;
while(!dq.empty()){
cnt++;
suma=sumb=0;
if(res&1){
while(suma<=pb&&!dq.empty()){
suma+=dq.front();
dq.pop_front();
}
ansa+=suma;
pa=suma;
}else{
while(sumb<=pa&&!dq.empty()){
sumb+=dq.back();
dq.pop_back();
}
ansb+=sumb;
pb=sumb;
}
res++;
}
cout<<cnt<<" "<<ansa<<" "<<ansb<<endl;
}
return 0;
}

E. Special Elements

分析

最好理解的一道题目🌝也是我唯一一道看了题解的题目😂一个前缀和,这道题数据量很小,只有8000,直接装进桶里就行了,而我就是没想到,一直在纠结怎么降低复杂度(好菜啊)求出每一个区间的和看看这个和对应的桶编号里面装没装数,其实是道水题

CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#define ios ios::sync_with_stdio(0)
using namespace std;
const int MAXN=1e4;
int val[MAXN],book[MAXN];
int main()
{
ios;
int t; cin>>t;
while(t--){
memset(book,0,sizeof book);
memset(val,0,sizeof val);
int n; cin>>n;
for(int i=1;i<=n;i++){
cin>>val[i];
book[val[i]]++;
val[i]+=val[i-1];
}
int cnt=0;
for(int i=0;i<n-1;i++){
for(int j=i+2;j<=n;j++){
int sum=val[j]-val[i];
// cout<<sum<<' '<<book[sum]<<endl;
if(sum<=n&&book[sum]){
cnt+=book[sum];
book[sum]=0;
}
}
}
cout<<cnt<<endl;
}
return 0;
}

F - Binary String Reconstruction

分析

又是思维题,给你一个n0,n1,n2让你构造一个二进制序列,这个序列子序列中00的个数为n0,01或10的个数为n1,11的个数为n2,首先n0和n2的序列容易构造,因为只包含一个数字,n1我们可以定义顺序为1010…n1=1:10 n1=2:101 n1=3:1010,每次增加一个数,单独构造容易,合起来难,三个序列合起来中间肯定会多出一些,所以只要在本上演算一下,再把多出的那一部分去掉就行了,然后我构造的序列顺序是n0n2n1,感觉这样构造简单🐶说实话我交代码时都没敢想能AC,因为感觉没考虑全,但是测试几组数据发现能过就抱着试一试的态度交上去了,结果A了:smile:

CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#define ios ios::sync_with_stdio(0)
using namespace std;
const int MAXN=1e4;
int val[MAXN],book[MAXN];
int main()
{
ios;
int t; cin>>t;
while(t--){
int n0,n1,n2;
string ans;
cin>>n0>>n1>>n2;
for(int i=1;i<=n0+1;i++){
if(n1!=0||n1==0&&n2==0) ans+="0";
}
for(int i=1;i<=n2;i++){
ans+="1";
}
for(int i=1;i<=n1;i++){
if(i%2) ans+="1";
else ans+="0";
}
if(n0==0&&n1==0) ans+="1";
cout<<ans<<endl;
}
return 0;
}

G - Special Permutation

分析

说实话我不知道这道题为啥放在最后,感觉难度并不大,反而挺简单的🌚就是让你构造一个相邻两个数之差的绝对值在2到4的区间内(闭区间),我们只要把奇偶分开就行了,但是我有一个疑问,我的思路是把偶数写在前面奇数的倒序列放在后面,例如:
8:2 4 6 8 7 5 3 1
很明显只有中间不符合条件,所以只动中间就行了,让7和5(奇数序列的前两个)交换:
8:2 4 6 8 5 7 3 1(满足条件)
再举个例子:
9:2 4 6 8 9 7 5 3 1
还是只动中间,因为9比8(奇数第一个和偶数最后一个)大所以让5跑到9中间(奇数第3个移动到奇数和偶数序列之间):
9:2 4 6 8 5 9 7 3 1(满足条件)
这样的思路我仔细想了想感觉没毛病,就交了,结果wrong了?我不服气,发现中间可能是换行的问题,又交又wrong…

我枯了,为啥?
后来换思路:
给2 4 1 3的序列两边添加数,先左后右轮换添加,例如:

  1. 8:2 4 1 3
  2. 8:5 2 4 1 3
  3. 8:5 2 4 1 3 6
  4. 8:7 5 2 4 1 3 6
  5. 8:7 5 2 4 1 3 6 8
    完成~,交了AC了。。AC后看了测试数据发现我原来的代码测试数据1应该是对的啊!希望网友那位可以为我解惑(不胜感激)

wrong CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#define ios ios::sync_with_stdio(0)
using namespace std;
const int MAXN=1e4;
void swap(int &a,int &b){
int t=a;
a=b;
b=t;
}
int val[MAXN],book[MAXN];
int main()
{
ios;
int t; cin>>t;
while(t--){
memset(val,0,sizeof val);
int n; cin>>n;
if(n==2||n==3){
cout<<-1<<endl;
continue;
}
int tail=0;
for(int i=2;i<=n;i+=2){
val[++tail]=i;
}
int flag=tail;
int p=n%2?n:n-1;
for(int i=p;i>=1;i-=2){
val[++tail]=i;
}
if(val[flag+1]<val[flag]) swap(val[flag+1],val[flag+2]);
else{
for(int i=1;i<=n;i++){
if(i==flag+1){
printf("%d%c",val[flag+3],i==n?'\n':' ');
}
if(i==flag+3){
continue;
}
printf("%d%c",val[i],i==n?'\n':' ');
}
if(n==5) cout<<endl;
continue;
}
for(int i=1;i<=n;i++) printf("%d%c",val[i],i==n?'\n':' ');
}
return 0;
}

AC CODE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
string ans;
void bd(int n){
if(n<=9){
ans=(char)(n+'0')+ans;
}else{
while(n!=0){
char c=(char)(n%10+'0');
ans=c+ans;
n/=10;
}
}
}
void pd(int n){
if(n<=9){
ans+=(char)(n+'0');
}else{
char ch[2000];
int tail=0;
while(n!=0){
char c=(char)(n%10+'0');
ch[++tail]=c;
n/=10;
}
for(int i=tail;i>=1;i--){
ans+=ch[i];
}
}
}
int main()
{
int t; cin>>t;
while(t--){
ans.clear();
int n; cin>>n;
if(n<=3){
puts("-1");
continue;
}
ans+="2 4 1 3";
int flag=1;
for(int i=5;i<=n;i++){
if(i%2){
ans=" "+ans;
bd(i);
}
else{
ans+=" ";
pd(i);
}
}
cout<<ans<<endl;
}

Ending~撒花不要白嫖了,留下一个赞吧👍