Codeforces Round #503 Div1 (by SIS) A,B
Codeforces Round #503 Div1 (by SIS) A,B
A.Elections
思路:
从数据范围可以看出 由于\(n\leq3000\),且题目要求: 得票数要严格大于其他所有人
于是我们不妨枚举第一个政客得票的数量,设为\(num\),且设现在支持第一个政客的值为\(val\)
分为两种情况讨论:
我们假设现在枚举的这个人原先的支持政客为\(x\)
1.原本就比\(x\)得票高 那我们就要去让支持\(x\)的人中最少花费的几人去支持第一个政客 使得第\(x\)个人的得票小于\(num\),\(val\)也要加上对应值
2.原本得票数比\(x\)低 那么我们先不用管它
在上述操作结束之后 我们的理想情况是让\(val==num\).可惜事与愿违 我们会碰到以下两种情况:
1.\(val\leq num\) 那么这时候我们便不用管哪个人支持谁 直接一直选花费最小的 直到\(val==num\)为止
2.\(val>num\) 这说明我们选多了 直接退出即可 因为这已经不在我们的控制范围内了 应该交给更大的\(num\)去处理
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=2e5+10;
const int INF=0x3f3f3f3f;
int n,m,ans=1e16;
struct node{
int id,val;
}p[maxn];
bool cmp(node x,node y){
return x.val<y.val;
}
int t[maxn],st[maxn],vis[maxn];
signed main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>p[i].id>>p[i].val,t[p[i].id]++;
sort(p+1,p+n+1,cmp);
for(int i=1;i<=n;i++){
int val=0,num=0;
for(int j=1;j<=m;j++)st[j]=t[j];
for(int j=1;j<=n;j++){
vis[j]=0;
if(p[j].id==1)num++,vis[j]=1;
if(st[p[j].id]>=i&&p[j].id!=1)st[p[j].id]--,val+=p[j].val,num++,vis[j]=1;
}
if(num>i)continue;
for(int j=1;j<=n;j++){
if(num==i)break;
if(vis[j])continue;
num++,val+=p[j].val;
}
ans=min(ans,val);
}
cout<<ans<<endl;
return 0;
}
B.The hat
思路:
很不错的一道交互题
我们先把它进行差分处理 可以得到\(n\)个1和\(n\)个-1
条件转化一下 使得\(a_i=a_{i+ \frac{n}{2}}\) 就是让\(i\)到\(i+\frac{2}{n}\)这个区间里的和为0(这里是对于1和-1来说的)
显然,如果\(n\) \(mod 4\) 不为0,那么\(\frac{n}{2}\)一定为奇数 则和一定不可能为0 直接输出-1即可
否则 我们考虑以下方法:
我们可以通过两次操作来得到一个区间里的和 通过观察不难得出 对于两个连续的区间 其和的变化要么是2,要么是0 更形式化一点:
\([i,i+\frac{n}{2}]\)与\([i+1,i+1+\frac{n}{2}]\)的差为2或0
我们可以对其进行二分处理:
如果区间\([i,i+\frac{n}{2}]\)和\([i+j,i+j+\frac{n}{2}]\)一个为正一个为负 那么其中一定有一个0
否则换一边二分即可
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
const int INF=0x3f3f3f3f;
int n;
int query(int l,int r){
int v1,v2;
cout<<"? "<<l<<endl;
fflush(stdout);
cin>>v1;
cout<<"? "<<r<<endl;
fflush(stdout);
cin>>v2;
return v2-v1;
}
int main(){
std::ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n;
if(n%4!=0)cout<<"! -1";
else{
int l=1,r=n/2;
while(l<=r){
int mid=(l+r)/2;
int s1=query(l,l+n/2);
int s2=query(mid,mid+n/2);
if(s1==0||s2==0){
cout<<"! ";
if(s1==0)cout<<l;
else cout<<mid;
break;
}
if(s1>s2)swap(s1,s2);
if(s1<0&&s2>0)r=mid-1;
else l=mid+1;
}
}
return 0;
}
浙公网安备 33010602011771号