A. Frog Jumping
题意:
青蛙先向右跳一次,再向左跳一次,又向右跳一次,再向左......,向右一次a个单位,向左一次b个单位,问跳k次后青蛙所在的位置,初始位置为0
题解:
一次右,一次左后位置为a-b,计算有多少个a-b,然后判个奇偶
代码:
#include <iostream>
using namespace std;
int main()
{
int a,b,k,t;
cin>>t;
while(t--)
{
cin>>a>>b>>k;
if(k&1)
{
cout<<1ll*(a-b)*(k/2)+a<<endl;
}
else cout<<1ll*(a-b)*(k/2)<<endl;
}
return 0;
}
B. Disturbed People
题意:
给你01串,当 且
时,你必须改变一个1为0,求最少的改变次数
题解:
贪心发现,每次改变 最优
代码:
#include <iostream>
using namespace std;
int a[150];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
cin>>a[i];
int ans = 0;
for(int i=2;i<n;++i)
{
if(!a[i])
{
if(a[i-1]&&a[i+1])
{
ans++;
a[i+1] = 0;
}
}
}
cout<<ans;
return 0;
}
C. Good Array
题意:
给你n个数,每次选择删除一个数,使得剩下n-1数中的n-2个数的和等于另一个数,求可以选择多少次
题解:
枚举删除,判断剩下的数中最大的哪一个数是否等于其他数的和
代码:
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int MAXN = 2e5+55;
ll a[MAXN];
ll b[MAXN];
int c[MAXN];
int main()
{
ll n;
cin>>n;
ll sum = 0;
for(int i=0;i<n;++i)
{
cin>>a[i];
b[i] = a[i];
sum += a[i];
}
sort(b,b+n,greater<ll>());//找到最大的两个数
int ans = 0;
for(int i=0;i<n;++i)
{
ll tep = sum - a[i];
if(a[i]==b[0])
{
if(tep-b[1]==b[1])
{
c[ans++]=i+1;
}
}
else
{
if(tep-b[0]==b[0])
c[ans++]=i+1;
}
}
cout<<ans<<endl;
for(int i=0;i<ans;++i)
cout<<c[i]<<" ";
return 0;
}
D. Cutting Out
题意:
在n个数中选出k个数,求能取出相同的k个数的次数的最大值,输出这k个数
题解:
不难发现,求满足条件的最大值,考虑二分答案 (不熟二分答案的戳这里~)
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
const int MAXN = 2e5+55;
using namespace std;
int a[MAXN];
int m,n,k,v;
bool check(int mid)
{
int p = 0;
for(int i=0;i<MAXN-22;++i)
{
p += a[i]/mid;
}
return p>=k? true:false ;
}
int main()
{
cin>>n>>k;
while(n--)
{
scanf("%d",&v);
a[v]++;
}
int l = 1;
int r = MAXN;
int ans=0;
while(l<=r)
{
int mid = (l+r)>>1;
if(check(mid))
{
l=mid+1;
ans = mid;
}
else r=mid-1;
}
for(int i=0;i<MAXN&&k;++i) //注意只输出k个
{
for(int j=1;j<=a[i]/ans&&k;++j)
{
printf("%d ",i);
k--;
}
}
return 0;
}
E. Thematic Contests
题意:
给你n个数,每次选一样大的数,第一次选任意个,其后选的数必须是前一次的2倍,求最多能选多少个数
题解:
对每个数计数,按个数从小到大排序,枚举第一次选的个数,二分查找下次能否满足
代码:
#include <map>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 2e5+55;
int a[MAXN];
int main()
{
map<int,int> p;
map<int,int> ::iterator it;
int n,v;
cin>>n;
while(n--)
{
scanf("%d",&v);
p[v]++;
}
int m=0;
for(it=p.begin();it!=p.end();++it)
{
a[m++] = it->second;
}
sort(a,a+m);
int ans = 0;
for(int i=1;i<=a[m-1];++i)
{
int pos = lower_bound(a,a+m,i)-a;
int sum = i;
int num = i;
while(1)
{
num *= 2;
int tep = lower_bound(a+pos+1,a+m,num)-a;
if(tep>pos&&tep<m)
{
sum += num;
pos = tep;
}
else break;
}
ans = max(sum,ans);
}
cout<<ans;
return 0;
}