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;
}
posted on 2023-01-13 22:11  C2023CYJ  阅读(33)  评论(0)    收藏  举报