SUM-ACM——VJ天梯训练赛
这次比赛我暴露了很多问题,一些模拟还有贪心思路错误。
补题如下:
E - E
题解:一道模拟题,我的问题在于不知道怎么替换下一个,就从0开始遍历数组然后数组的值--,如果为零就continue下一个,这个问题在于无法遍历完所有的数,会少算。其实只需要把接完水的按顺序到下一个就可以了,这样还有一个问题在于有可能前面的数一直在接水接到最后,这样的话我们只需要把剩下没有接完的找它的最大值就可以了。
题目如下:
代码如下:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int v[100000];
int main ()
{
ios::sync_with_stdio(false);
int n,m;
int t= 0;
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>v[i];
}
int q = m;
while(q<=n)
{
for(int i=0;i<m;i++){
v[i]--;
if(!v[i])
{
v[i]=v[q++];//这里就可以按照顺序让下一个接水,这个是我的不懂之处,我只想着每一个人接水就加一但是忽略了前面没有接完,或者中间没有接完的情况,思路混乱。
}
}
t++;
}
for(int i=1;i<m;i++){
if(v[i]>v[0])
v[0]=v[i]; //这里可以找出剩下没有接水完的里面的最大的接水数
}
cout<<t+v[0]; //求和
}
F - F
题解:由题目可知这个数必须为2的幂的形式,且不能为0,那么这个数不可能为奇数,奇数输出-1即可,然后分析题目的意思,这个数是由不同的正整数得到的也就是说明它的幂是不一样的数,那么我们只需要把这个数化成二进制的形式然后对应的位置乘2的数相加即可。
题目如下:
代码如下:
点击查看代码
#include <bits/stdc++.h>
using namespace std;
int main ()
{
int n;
vector <int> v;
int p=1;
cin>>n;
int t=n;
if(n%2!=0)
{
cout<<-1;
return 0;
}else
{
while(n>0)
{
if(n%2!=0)
{
v.push_back((n%2)*p);
}
p*=2;
n/=2;
}
}
if(v.size()==0)
{
cout<<-1;
return 0;
}
int sum = 0;
for(int i=v.size()-1;i>=0;i--){
sum+=v[i];
}
if(sum!=t)
{
cout<<-1;
return 0;
}
for(int i=v.size()-1;i>=0;i--){
cout<<v[i]<<" ";
}
}
代码如下:
点击查看代码
#include<bits/stdc++.h>
using namespace std;
int n;
int v[100005];
int ans;
struct Node{
int t;
int x;
Node(int a,int b){
t=a,x=b;
}
};
deque<Node>q;//双端队列
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int t,k,x;
scanf("%d%d",&t,&k);
for(int j=1;j<=k;j++){
scanf("%d",&x);
if(!v[x]) ans++;//新增国籍
v[x]++;//该国籍人数增加
q.push_back(Node(t,x));//入队
}
while(t-q.front().t>=86400){//离开区间
v[q.front().x]--;//该国籍人数减少
if(!v[q.front().x]) ans--;//这个国籍没人了,总数减少
q.pop_front();//出队
}
printf("%d\n",ans);
}
return 0;
}