https://codeforces.ml/contest/1348
晚上的刷题计划正式启动了 所以每天早上记录一下
昨晚挑了这一场 感觉好难 看了下队友们的当时的情况
好像都不怎么乐观 大家都在掉分(还好当时没打 hhhh)
就出了ab两题昨晚
cd终于补完了
A. Phoenix and Balance
题目思路
直接两两配对相减 就好了
ac代码
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 1e5+10;
const int inf = 0x1f1f1f1f;
const int mod = 2333;
int a[maxn],b[maxn];
map<int,int>mp;
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int tem=1;
ll ans=0;
for(int i=1;i<=n/2;i++)
{
tem*=2;
ans+=tem;
}
printf("%lld\n",ans);
}
}
B. Phoenix and Beauty
题目思路
题目给出n个数 要求输出是每个长度为k的区间和要相同
一直想着直接构造数组 但是要么mle 要么re 很头疼
看了下题解 说用set记录出现了多少种不同的数
构造一个长度为k的循环节
然后输出n边就好了
(菜鸡不晓得用set 写了快一个小时才搞好)
ac代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 1e7+10;
const int inf = 0x1f1f1f1f;
const int mod = 2333;
int a[maxn];
set<int>s;
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
s.clear();
int n,k,cnt=0;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
s.insert(a[i]);
}
if(s.size()>k)//如果出现的不同数值多余k那么一定无法满足题目条件
printf("-1\n");
else
{
printf("%d\n",n*k);
for(int i=0;i<n;i++)
{
for(set<int>::iterator it=s.begin();it!=s.end();it++)
{
printf("%d ",*it);
}
for(int j=s.size();j<k;j++)
printf("1 ");
}
printf("\n");
}
}
}
来补c题了
C - Phoenix and Distribution
题目思路
看完题目啥思路都没有 甚至题意都不是很懂
看了好久题解才搞懂这道题到底咋做
题目给出字符串长度n和要分成的区间个数k
要求输出区间字典序的最大值最小时的区间包含的字符串
就挺头疼的看完题目 很考分析的一道题
首先根据题意 结果与原串字符顺序无关 故先对原串排序
然后按照顺序将前k个字符装入k个桶
之后判断最小的那个字符是否够排满k个桶
不能的话直接输出第k个字符就好了 k后面的数直接装到前面
这是第k个桶的字典序最大 并且是所有最大值中最小的
能的话再进行分析
后面的所有字符是否相同
相同就将后面的字符均摊在k个桶中
如果不同就把所有的值全部放到第一个桶中
这里我也讲不太清为什么 原谅我这个菜鸡 建议结合字典序定义进行理解
这题的分析还是很巧妙地 很适合我这种菜鸡学习
ac代码
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 2e5+10;
const int inf = 0x1f1f1f1f;
const int mod = 2333;
string a,s;
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
int n,k;
scanf("%d%d",&n,&k);
cin>>a;
sort(a.begin(),a.end());
if(a[k-1]!=a[0])
cout<<a[k-1];
else
{
int flag=0;
for(int i=k;i<a.length()-1;i++)
{
if(a[i]!=a[i+1])
{
flag=1;
break;
}
}
if(flag==1)
{
for(int i=k-1;i<a.length();i++)
cout<<a[i];
}else
{
for(int i=0;i<a.length();i+=k)
cout<<a[i];
}
}
printf("\n");
}
}
d待补
D. Phoenix and Science
题目思路
因为分裂只是影响每天晚上加的值 所以题目下面的那些花里胡哨的小数都没啥用
首先将n分解 从1开始减 每次将减的数乘二并加入数组 最后剩下的数也加入数组 并排序 这就是每晚要增加的数的最优解的一种
举个例子
20 分解成1 2 4 8 5 排序后为1 2 4 5 8
具体操作见代码
ac代码
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 2e5+10;
const int inf = 0x1f1f1f1f;
const ll llinf =1e17+10;
const int mod = 2333;
int a[maxn],sum[maxn];
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int cnt=0;
int tem=n;
int c=1;
while(tem>=c)
{
tem-=c;
a[cnt++]=c;
c*=2;
}
if(tem>0)
a[cnt++]=tem;//这里要注意特判一下0 防止0来影响数组
sort(a,a+cnt);
printf("%d\n",cnt-1);
for(int i=1;i<cnt;i++)
{
printf("%d ",a[i]-a[i-1]);
}
printf("\n");
}
}