Codeforces 687 div2

明天来写
最近准备考试,写的不太详细,哪里看不懂直接私信就行。
A:
这个题直接猜了一下就是求4个点到r,c的距离哪个最大

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int t;
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        int n,m,r,c;
        scanf("%d%d%d%d",&n,&m,&r,&c);
        int sum=0;
        sum=max(sum,abs(n-r)+abs(m-c));
        sum=max(sum,abs(r-1)+abs(c-1));
        sum=max(sum,abs(r-1)+abs(m-c));
        sum=max(sum,abs(n-r)+abs(c-1));
        printf("%d\n",sum);
    }
 } 

B:
n=1e5,c=100,这范围直接暴力每个颜色就好了

#include<bits/stdc++.h>

using namespace std;

const int N = 1e5+10;

int c[N];

void solve()
{
    map<int,int> mp;
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&c[i]),mp[c[i]]=1;
    int cnt=1000000;
    for(int i=1;i<=100;i++)
    {
        if(mp[i]==0) continue;
        int cnt1=0;
        for(int j=1;j<=n;)
        {
            if(c[j]!=i) 
            {
                cnt1++;
                j+=k;
                //cout<<j<<" "<<cnt1<<endl;
            }
            else j++;
        }

        cnt=min(cnt1,cnt);
    }
    printf("%d\n",cnt);
}

int main()
{
    int t;    
    scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        solve();
    }
}

C:
一开始是写的nk复杂度从前面往后算,然后T了,想了想发现只需要从后往前跳,就可以以O(n)的复杂度来解决了。

include<bits/stdc++.h>

typedef long long ll;

const int N= 1e6+10;;
const ll INF = 0x3f3f3f3f3f3f3f3f;
using namespace std;

ll n,m,p;
ll num[N];
char s[N];
ll hz[N];
int a[N];
void solve()
{
        scanf("%lld%lld%lld",&n,&m,&p);
        for(int i=1;i<=n+2*p;i++) hz[i] = 0;

        for(int i=1;i<=n;i++)
        {
            scanf("%1d",&a[i]);
        }
        ll x,y;
        scanf("%lld%lld",&x,&y);
        ll res = INF;
        for(int i=n;i>=1;i--){
            hz[i] = hz[i+p];
            if(a[i] == 0) hz[i] += x;
        }
        for(int i=m;i<=n;i++)
            res = min(res,(i-m)*y+hz[i]);
        printf("%lld\n",res);
}

int main(){
    int T;scanf("%d",&T);
    for(int i=1;i<=T;i++)
     solve();
    return 0;
}

D:
如果n>60的话。我们设每个值最高位在第i位,因为长度最多为30,所以n>60时,一定会有连续的3个在一起只需要把两个异或就小于另一个了。n<60的时候就暴力

#include<bits/stdc++.h>

using namespace std;

const int N = 1e5+10; 
int a[N];
int sum[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]^a[i];
    }
    if(n>60) printf("1\n");
    else {

        int ans=1000000;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<i;j++)
            {
                for(int k=i+1;k<=n;k++)
                {
                    if(k-j>2&&(sum[j]^sum[i])>(sum[i]^sum[k]))
                    {
                        ans=min(ans,k-j-2); 
                    }
                }
            }
        }
        if(ans==1e6) ans=-1;
        cout<<ans<<endl;

    }
} 

E:
这个题先从大到小排序,然后从第一个加如果pre<0的话。
这个时候我们就需要对这个当前位置之后的还有当前的pre处理。
因为我们有k个最后一个不需要加,相当于是k+1个,只要把这些分组分到k+1个就好了。第一个是0次贡献,第二个是1次贡献,依次类推

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 5e5+10;
ll c[N];
vector<ll> ve;

bool cmp( int a,int b)
{
    return a>b;
}
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&c[i]);
    } 
    sort(c+1,c+n+1,cmp); 
    ll pre=0;
    ll sum=0;
    int st=n+1;
    int flag=0;
    for(int i=1;i<=n;i++)
    {
        //cout<<sum<<endl;
        sum+=pre;
        pre+=c[i];
        //cout<<"pre:"<<pre<<endl;
        if(pre<0)
        {
            ve.push_back(pre);
            st=i+1;
            break;
        }
    }
//    cout<<"st:"<<st<<endl;
    for(int i=st;i<=n;i++)
    {
        ve.push_back(c[i]);

    }
    sort(ve.begin(),ve.end());
    for(int i=0;i<ve.size();i++)
    sum+=(1LL*ve[i]*(i/(k+1)));


    cout<<sum<<endl;


}
全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务