比赛
难得一见div4的场.也是第一次体会到了AK的快乐(虽然打的是virtual).难度应该在div2的ABC吧.码风以暴力为主.
A - Sum of Round Numbers
题目大题:给一个数,把每一位拆出来.
比如5423拆成 5000 400 20 3
就拆就完事了…
代码
#pragma GCC optimize(3)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void write(int k) {
if (k < 0)
putchar('-'), k = -k;
if (k >= 10)
write(k / 10);
putchar(k % 10 + '0');
}
int f[5] = {1,10,100,1000,10000};
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
int tn = n;
int cnt= 0;
int ans = 0;
while(tn){
if(tn%10) ans++;
tn/=10;
cnt++;
}
int i = 0;
cout <<ans << endl;
while(n){
if(n%10){
cout << n%10*f[i] << " ";
}
n/=10;
i++;
}
cout << endl;
}
return 0;
}
B - Same Parity Summands
题目大意:给一个n和k 只能用k个奇数或者偶数去凑n.可以重复选同一个数字.
有两种无解的情况
第一种:n是奇数,k是偶数 这种是一定无法解决的.
第二种:如果我们用奇数去凑肯定尽量先用1去凑.如果说n < k的话就凑不出来,偶数同理.
代码
#pragma GCC optimize(3)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void write(int k) {
if (k < 0)
putchar('-'), k = -k;
if (k >= 10)
write(k / 10);
putchar(k % 10 + '0');
}
int main(){
int t,n,k;
cin >> t;
while(t--){
cin >> n >> k;
if((n & 1) == (k & 1)){
if(n < k){
puts("NO");
continue;
}
int sum = 0;
puts("YES");
fir(i,1,k-1){
sum += 1;
cout << 1 << " ";
}
cout << n - sum << endl;
}
else if((n & 1) && !(k & 1)) puts("NO");
else{
if(n < 2*k){
puts("NO");
continue;
}
puts("YES");
int sum = 0;
fir(i,1,k-1){
sum += 2;
cout << 2 << " ";
}
cout << n-sum << endl;
}
}
return 0;
}
C - K-th Not Divisible by n
题目大意:找第k个不能被n整除的数.
显然出现的频率是n-1,n-1,n-1这样子.就n×k/(n-1) + k%(n-1) .特别是如果n%(n-1) == 0 时 答案是 n×k/(n-1) - 1 具体模拟几个样例就知道答案了.
#pragma GCC optimize(3)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void write(int k) {
if (k < 0)
putchar('-'), k = -k;
if (k >= 10)
write(k / 10);
putchar(k % 10 + '0');
}
int t;
int main(){
cin >> t;
while(t--){
int n,k;
cin >> n >> k;
int t1 = k/(n-1),t2 = k%(n-1);
if(!t2) t2--;
cout << t1*n + t2 << endl;
}
return 0;
}
D - Alice, Bob and Candies
题目大意:这题目长的就离谱.就是一个人从头开始吃,一个人从尾开始吃.每次都要吃的比另外一个人多了才停下来,问最后吃了多少次,两个人分别吃了多少.
模拟题,两个指针一指按题目模拟就完事了
#pragma GCC optimize(3)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void write(int k) {
if (k < 0)
putchar('-'), k = -k;
if (k >= 10)
write(k / 10);
putchar(k % 10 + '0');
}
int a[N];
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
fir(i,1,n){
cin >> a[i];
}
int ans = 0,sum1=0,sum2=0,tmp1=0,tmp2=0;
int i = 0,j = n+1;
bool f = 1;
while(i < j-1){
bool f1 = 0;
if(f){
ans++;
while(!f1 || tmp1 <= tmp2){
f1 = 1;
tmp1 += a[++i];
sum1 += a[i];
if(i == j-1) break;
}
tmp2 = 0;
}
else{
ans++;
while(!f1 || tmp2 <= tmp1){
f1 = 1;
tmp2 += a[--j];
sum2 += a[j];
if(i == j-1) break;
}
tmp1= 0;
}
f = !f;
}
cout << ans << " " << sum1 << " " << sum2 << endl;
}
return 0;
}
E - Special Elements
题目大意:给n个数,如果一个数可以表示为某个大于2的区间的和,那么他就是特殊元素,问一共有多少个特殊元素.
这题还有点意思.唯一的WA贡献给了这题. 其实不难.我们转化一下问题.先求出前缀和.对每个a[i] 找到一个sum[r]-sum[l] = a[i] 问题就是怎么统计sum[r]-sum[l]了,这里有一个很好的性质.因为数最大不超过8e3.我们用一个数组去存小于8e3的sum[r]-sum[l]就可以了.超过了就舍弃. 虽然是两重循环但是肯定不会循环太多次.
#pragma GCC optimize(3)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 8e3+10;
const int mod = 9901;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void write(int k) {
if (k < 0)
putchar('-'), k = -k;
if (k >= 10)
write(k / 10);
putchar(k % 10 + '0');
}
int a[N],s[N],vis[N];
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
int ans = 0;
int mx = 0;
mem(vis,0);
fir(i,1,n) cin >> a[i],mx = max(mx,a[i]);
fir(i,1,n) s[i] = s[i-1] + a[i];
fir(i,1,n){
fir(j,i+1,n){
if(s[j] - s[i-1] > mx) break;
vis [s[j] - s[i-1]] = 1;
}
}
fir(i,1,n){
if(vis[a[i]]){
ans++;
}
}
cout <<ans << endl;
}
return 0;
}
F - Binary String Reconstruction
题目大意:定义了三种字符串. 00 (01 10)这是同一种. 11 . 给了三种字符串的数量.让你构造一个字符串恰好等于给的数量.
先构造00 再构造 11 最后构造 01 这样一定能构造出答案. 我的代码复杂了一点.判定了 n0 或者 n2 为0的情况 不过也不难构造.纸上模拟一下就好了.
#pragma GCC optimize(3)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int mod = 9901;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void write(int k) {
if (k < 0)
putchar('-'), k = -k;
if (k >= 10)
write(k / 10);
putchar(k % 10 + '0');
}
int main(){
int t;
cin >> t;
while(t--){
int a,b,c;
cin >> a >> b >> c;
string ans = "";
if(c){
if(a){
fir(i,1,a+1){
ans += '0';
}
b--;
}
fir(i,1,c+1){
ans += '1';
}
fir(i,1,b){
if(i&1) ans += '0';
else ans +='1';
}
}
else{
if(a){
fir(i,1,a+1){
ans += '0';
}
fir(i,1,b){
if(i&1) ans += '1';
else ans += '0';
}
}
else{
fir(i,1,b+1){
if(i&1) ans += '1';
else ans += '0';
}
}
}
cout << ans << endl;
}
return 0;
}
G - Special Permutation
题目大意:构造一个n的全排列.满足abs(a[i]-a[i+1])绝对值在[2,4]内
暴力构造就好了. 比如n == 12. 1 3 5 7 9 11 8 12 10 6 4 2. 就这样子去构造.先把奇数写完,然后判定一下下面三个偶数要填几.暴力的去填就完事了.我的代码也是突出了一个暴力.
#pragma GCC optimize(3)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define pll pair<long long,long long>
#define pdd pair<double,double>
#define db double
#define fir(i,a,b) for(int i=a;i<=b;++i)
#define afir(i,a,b) for(int i=a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3+10;
const int mod = 9901;
inline int read(){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void write(int k) {
if (k < 0)
putchar('-'), k = -k;
if (k >= 10)
write(k / 10);
putchar(k % 10 + '0');
}
int main(){
int t;
cin >> t;
while(t--){
int n;
cin >> n;
if(n <=3) puts("-1");
else if( n== 4) cout << 3 << " " << 1 << " " << 4 << " " << 2 << endl;
else{
vi ans;
int cnt = 0;
fir(i,1,n){
if(i*2 - 1 > n) break;
ans.pb(i*2-1);
cnt++;
}
if(n&1){
ans.pb((cnt-2)*2);
ans.pb((cnt-1)*2);
cnt--;
}
else{
ans.pb((cnt-2)*2);
ans.pb((cnt)*2);
ans.pb((cnt-1)*2);
cnt --;
}
afir(i,cnt-2,1) ans.pb(i*2);
fir(i,0,ans.size()-1) cout << ans[i] << " ";
cout << endl;
}
}
return 0;
}