11.22 Educational Codeforces Round 71 (Rated for Div. 2)

总结:

dp没做出来需要反省一下…

A - There Are Two Types Of Burgers

思路:贪心,把单价高的先做出来,剩下的材料再做单价低的。

#include<bits/stdc++.h>
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
 
const int manx=1e5+5;
 
int main()
{
    ll t=read();
    while(t--)
    {
        ll b=read(),p=read(),f=read(),h=read(),c=read(),x=0,y=0;
        if(h<c) swap(h,c),swap(p,f);
        if(b>2*p) x=h*p;
        else x=h*b;
        b-=2*p;
        if(b>2*f)  y=c*f;
        else y=c*b;
        if(y<0) y=0;
        cout<<x+y<<endl;
    }
 
    return 0;
}

B - Square Filling

思路:开三份地图,a原地图,b作为输出,c作为对比,只要ac不相同就输出-1,否则输出b中1的坐标。

#include<bits/stdc++.h>
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
 
const int manx=100;
ll a[manx][manx],b[manx][manx],c[manx][manx];
 
int main()
{
    ll n=read(),m=read(),ans=0,flag=0;
    memset(b,0,sizeof(b));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            a[i][j]=read();
            if(a[i][j]) flag=1;
        }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(a[i][j]&&a[i+1][j]&&a[i][j+1]&&a[i+1][j+1])
            {
                b[i][j]=1;
                ans++;
                c[i][j]=c[i+1][j]=c[i][j+1]=c[i+1][j+1]=1;
            }
    if(flag  && !ans) put3();
    else{
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(c[i][j]!=a[i][j])
                {
                    put3();
                    return 0;
                }
        cout<<ans<<endl;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(a[i][j]&&b[i][j])
                    cout<<i<<" "<<j<<endl;
    }
    return 0;
}

C - Gas Pipeline

思路:dp[i][0]表示不抬高,dp[i][1]表示抬高,详细见代码注释。

#include<bits/stdc++.h>
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
 
const int manx=2e5+5;
ll dp[manx][2];
 
int main()
{
    ll p=read();
    while(p--)
    {
        ll n=read(),a=read(),b=read();
        string s;
        cin>>s;
        memset(dp,inf,sizeof(dp));
        dp[0][0]=b; //一开始需要一根黑水管
        for(int i=0;i<n;i++)
        {
            if(s[i]=='0'){
                dp[i+1][0]=min(dp[i][0],dp[i][1]+a)+a+b; //0的话水平不变
                // 1到0和0到1 都 需要多一个红色水管
                dp[i+1][1]=min(dp[i][0]+a,dp[i][1])+a+b+b;
                // 1到1需要多一根黑色水管
            }
            else dp[i+1][1]=dp[i][1]+b+a+b;
            //当i为1,那么dp[i][0]不存在
        }
        cout<<dp[n][0]<<endl;
    }
    return 0;
}

D. Number Of Permutations

思路:组合数学,答案=全排列-左边不单调递减-右边不单调递减+左右边同时不单调递减的,用两个hash数组标记左右两边的出现次数,用map维护pair对出现次数,当对二元组的第一个元素进行排序后,整个二元组有出现降序状况,即表示重复二元组对答案没有贡献,即没有重复方案。

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define mod 998244353
using namespace std;
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
 
const int manx=3e5+5;
 
pair<ll,ll>a[manx];
map<pair<ll,ll>,ll>b;
ll L[manx],R[manx];
 
int main()
{
    ll n=read();
    ll f=1,l=1,r=1,cnt=1,ans=0;
    for(int i=1;i<=n;i++)
    {
        a[i].first=read(),a[i].second=read();
        f=f*i%mod,l=l*(++L[a[i].first])%mod,r=r*(++R[a[i].second])%mod,cnt=cnt*(++b[a[i]])%mod;
    }
    sort(a+1,a+1+n);
    for(int i=2;i<=n;i++)
        if(a[i].second<a[i-1].second)
            cnt=0;
    ans=f-l-r+cnt;
    cout<<(ans%mod+mod)%mod<<endl;
    return 0;
}

E. XOR Guessing

思路:交互题,询问100个数xor x ,询问两次求出x , 数据最多只有2^14-1, 所以可以分两次决定前7和后7位。

#include<bits/stdc++.h>
#define ll long long
#define R register int
#define inf 0x3f3f3f3f
#define mod 1000000007;
using namespace std;
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
void put1(){ puts("YES") ;}
void put2(){ puts("NO") ;}
void put3(){ puts("-1"); }
 
const int manx=2e5+5;
 
ll x,y;
 
int main()
{
    cout<<"? ";
    for(int i=1;i<=100;i++) cout<<i<<" ";
    cout<<endl<<"? ";
    for(int i=1;i<=100;i++) cout<<i*128<<" ";
    cout<<endl;
    cin>>x>>y;
    cout<<"! "<<x/128*128+y%128<<endl;
    return 0;
}
发布了50 篇原创文章 · 获赞 15 · 访问量 4241

猜你喜欢

转载自blog.csdn.net/JiangHxin/article/details/103204939