A. Frog Jumping
题目链接:https://codeforces.com/contest/1077/problem/A
题目大意:t组测试数据,从0开始,向前跳a,向后跳b,跳k次,输出最后所在的位置。
题解:大水题,直接输出就行了
int main()
{
std::ios::sync_with_stdio(false);
int t;
while(cin>>t)
{
ll a,b,k;
for(int i=1;i<=t;++i)
{
cin>>a>>b>>k;
if(k%2)
cout<<a*(k/2)-b*(k/2)+a<<endl;
else
cout<<(a-b)*(k/2)<<endl;
}
}
}
B. Disturbed People
题目链接:https://codeforces.com/contest/1077/problem/B
题目大意:n个数,每个数有0 || 1两种状态,0代表关灯睡觉,1代表开灯不睡觉,一个睡觉的如果两边都是开着灯的就会不开心(开灯的一直都开心),问最少熄灭多少盏灯能够让所有人都开心。
题解:贪心水题,对于每个不开心的人,熄灭后面的那一盏,因为只有后面的那一盏灯会对才会对后面的产生影响。
const int MAXN=2e5+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
int vis[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
clean(vis,0);
for(int i=1;i<=n;++i)
cin>>vis[i];
int ans=0;
for(int i=1;i<=n;++i)
{
if(vis[i]==0)//��ס��˯��
{
if(vis[i-1]&&vis[i+1])//��ס��������
{
ans++;
vis[i+1]=0;
}
}
}
cout<<ans<<endl;
}
}
C. Good Array
题目链接:https://codeforces.com/contest/1077/problem/C
题目大意:好数组的定义是:一个数组里面存在一个数,使得这个数组其他元素之和等于该数。我们可以从一个数组中去掉一个数来使它成为一个好数组,对于每个数组,输出所有能够去掉的一个元素使它能够构成一个好数组的元素(一次只能去掉一个)
题解:对于每个数组,求出它的和 sum,然后对于每个 a[i] 都判断一次,是否等于(sum-a[i])>>1,不等于则略过,等于则标记,最后输出即可。
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
//#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ˮӡ
//std::ios::sync_with_stdio(false);
const int MAXN=1e6+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
int vis[MAXN];
int arr[MAXN];
int ansvis[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
clean(vis,0);
clean(arr,0);
clean(ansvis,0);
ll sum=0;
for(int i=1;i<=n;++i)
{
cin>>arr[i];
sum+=arr[i];
vis[arr[i]]++;
}
int ans=0;
ll res;
for(int i=1;i<=n;++i)
{
res=sum-arr[i];//ȡ����һ����
if(res>2*MAXN)
continue;
vis[arr[i]]--;//��λ�õ���--
if(vis[res>>1] && res%2==0)//��������� && ����Ҫ��
{
ans++;
ansvis[i]=1;
}
vis[arr[i]]++;//�ظ�
}
if(ans)
{
cout<<ans<<endl;
for(int i=1;i<MAXN;++i)
{
if(ansvis[i])
cout<<i<<" ";
}
cout<<endl;
}
else
cout<<0<<endl;
}
}
D. Cutting Out
题目链接:https://codeforces.com/contest/1077/problem/D
题目大意:给出n个数,这n个数构成一个数组,可以从中提取出无限的有k个元素的数组,问提取后使原数组的元素个数最少的k个元素的数组使什么,随便输出一个就行。
题解:刚拿到题之后比较懵逼,试着用每次都除以二来找。。但是发现不行。。后来考虑用二分出符合要求的循环次数,然后遍历,发现可行,之后又复习了一下二分。。,大概思路就是:对于原数组,二分出最少的循环次数,然后找出符合要求的k个元素
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
//#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
const int MAXN=2e5+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
int arr[MAXN],num[MAXN],ans[MAXN];
int judge(int mid)
{
int res=0;
for(int i=1;i<MAXN;++i)
{
if(num[i]>=mid)
res+=num[i]/mid;//res新加入 num[i]/mid 个元素能重复出现mid轮
}
return res;//res个字符重复出现mid轮
}
int main()
{
std::ios::sync_with_stdio(false);
int n,k;
while(cin>>n>>k)
{
clean(num,0);
clean(ans,0);
for(int i=1;i<=n;++i)
{
cin>>arr[i];
num[arr[i]]++;
}
int l=1,r=n,mid,max_cyc;
while(r>=l)
{
//cout<<mid<<" "<<l<<" "<<r<<endl;
mid=(l+r)>>1;
if(judge(mid)>=k)//res个字符重复出现mid轮 && 能够输出k个字符
{//应该轮数更少才行
max_cyc=mid;
l=mid+1;
}
else
r=mid-1;
}
//此时得出的轮数是max_cyc
int tot=0,cyc;
for(int i=1;i<MAXN;++i)
{
cyc=num[i]/max_cyc;
if(cyc>0)
{
for(int j=1;j<=cyc;++j)
{
ans[tot++]=i;
if(tot==k)
break;
}
}
if(tot==k)
break;
}
for(int i=0;i<k;++i)
cout<<ans[i]<<" ";
cout<<endl;
}
}
E. Thematic Contests
题目链接:https://codeforces.com/contest/1077/problem/E
题目大意:给出一个数n,然后是n个数,每个数代表这个问题的种类,要求出一套题,每种问题的个数都是2倍的向上增加的,求出可以选择的最多的题目数量。
题解:由于ai的数据范围比较大,所以首先离散化一下数据,然后按照出现的次数排序,在之后,先选最多的,从后往前依次找/2的问题的个数,能找到则加上,找不到则说明这个问题的序列已经到了尽头,(注意一下,这个数要是偶数,因为如果它是奇数的话,就不能和前面的数构成二倍的关系)
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
const int MAXN=2e5+10;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
int arr[MAXN],vis[MAXN];
map<int,int> mp;
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
mp.clear();
clean(arr,0);
clean(vis,0);
for(int i=1;i<=n;++i)
cin>>arr[i];
int k=1;
for(int i=1;i<=n;++i)//数据离散化
{
if(mp[arr[i]]==0)
mp[arr[i]]=k++;
}
for(int i=1;i<=n;++i)//遍历数组,将它转换成出现的次数
vis[mp[arr[i]]]++;
sort(vis,vis+k);//升序遍历
int ans=0;
for(int i=1;i<=vis[k-1];++i)
{
int choose=k-1;//从后往前找 ,用最多的选上i
int num=i,res=0+num;//一开始选择i个问题 ,res=0+i
while(num%2==0&&choose>0)
{
num=num>>1;
choose--;
if(vis[choose]<num)
break;
res+=num;
}
ans=max(ans,res);
}
cout<<ans<<endl;
}
}