Codeforces Round #610 (Div. 2)【A - D】

题目来源:https://codeforces.com/contest/1282
脑速不够,差点掉分了,勉强上蓝,算是圣诞礼物了叭~
最可怕的是 发生了暑假一样的错误:
两个int型变量相乘然后爆了,希望以后不会再犯了!!!


1282A - Temporarily unavailable

这题可以说考的就是求x轴上两线段的重复的长度,但是我居然debug了18分钟…
我当时AC的代码 枚举每一种情况 (我是码农)

#include
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;

const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;

int n, m;
template<class T>
inline void read(T &x) {
    char c;
    x = 1;
    while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
    T res = c - '0';
    while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
    x *= res;
}
int main() {
    int t;
    r(t);
    while(t--){
        int a,b,c,r;
        rrr(a,b,c); r(r);
        if(a>b) swap(a,b);
        int ans=0;
        int x=c-r;
        int y=c+r;
        if(x<=a&&b<=y){
            cout<<0<<endl;
            continue;
        }
        else if(x<=a&&a<=y){
            cout<<b-y<<endl;
            continue;
        }
        else if(x<=b&&b<=y){
            cout<<x-a<<endl;
            continue;
        }
        if(a<=x&&y<=b){
            cout<<b-a-(y-x)<<endl;
        }
        else{
            cout<<b-a<<endl;
        }
    }
    return 0;
}

优化后简单的代码

#include
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;

const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;

int n, m;
template<class T>
inline void read(T &x) {
    char c;
    x = 1;
    while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
    T res = c - '0';
    while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
    x *= res;
}

int main() {
    int t;
    r(t);
    while(t--){
        int a,b,c,r;
        rrr(a,b,c); r(r);
        int x=c-r,y=c+r;
        if(a>b) swap(a,b);
        cout<<b-a-max(0,min(b,y)-max(a,x))<<endl;
    }
    return 0;
}

1282B - K for the Price of One

(Easy & Hard Version)
把价格排序之后不难发现 想用最少的钱买最多的肯定是把最靠前的都给买了
我把它当做dp处理了 dp[ i ]表示买前i个最少花多少钱
转移方程dp[i] = min(dp[i], dp[i - k] + f[i])
然后注意 dp[ i ] 不是逐渐增大的 ,我们要找最大的满足的i就ok了 故要倒着找

#include
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;

const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;

int n, m;
int f[N<<2];
LL dp[N<<2];
template<class T>
inline void read(T &x) {
    char c;
    x = 1;
    while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
    T res = c - '0';
    while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
    x *= res;
}
int main() {
    int t;
    r(t);
    while(t--) {
        r(n);
        r(m);
        int k;
        r(k);
        FOR(i, 1, n) r(f[i]);
        sort(f + 1, f + n + 1);
        int ans = 0;
        dp[0] = 0;
        for (int i = 1; i <= n; i++) {
            dp[i] = dp[i - 1] + f[i];
            if (i >= k) {
                dp[i] = min(dp[i], dp[i - k] + f[i]);
            }
        }
        for(int i=n;i>=0;i--){
            if(m>=dp[i]){
                cout<<i<<endl;
                break;
            }
        }
    }
    return 0;
}

1282C - Petya and Exam

这题考虑起来就是 先对ti 排序 ,每次考虑ti-1的时间能不能容纳前i-1个任务完成,能完成还要看能不能容纳i之后的任务先考虑简单任务,再考虑复杂任务,这也是贪心的一部分)
可怜,我再一次因为爆int而过了pretest没过终测,希望长点记性~

#include
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;

const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;

int n, m;
struct node
{
    int x,y;
}f[N<<2];
bool cmp(node a,node b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}
template<class T>
inline void read(T &x) {
    char c;
    x = 1;
    while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
    T res = c - '0';
    while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
    x *= res;
}
int main() {
    int t;
    r(t);
    while(t--) {
        int x,y;
        rrr(n,m,x); r(y);
        int n0=0,n1=0;
        FOR(i,1,n){
            r(f[i].y);
            if(f[i].y) n1++;
            else n0++;
        }
        FOR(i,1,n) r(f[i].x);
        sort(f+1,f+n+1,cmp);
        int ans=0;
        LL need=0;
        f[n+1].x=m+1;
        f[n+1].y=2;
        f[0].x=0;
        f[0].y=2;
        for(int i=0;i<=n;i++){
            if(f[i].y==0){
                need+=x;
                n0--;
            }
            else if(f[i].y==1){
                need+=y;
                n1--;
            }
            if(need>m) break;
            else if(need<=f[i+1].x-1) {
                int now=i;
                LL res=f[i+1].x-1-need;
                if(1ll*x*n0>res){
                    now+=res/x;
                }
                else{
                    now+=n0;
                    res-=1ll*n0*x;
                    if(1ll*y*n1>res){
                        now+=res/y;
                    }
                    else{
                        now+=n1;
                    }
                }
                ans=max(ans,now);
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

1282D - Enchanted Artifact

这题是一道特殊的人机互动题,什么是互动题自行查找
我也是比赛前一小时才知道什么是互动题的,可惜前面卡太久了,这些题没时间做了 555 算了放一个介绍链接吧
怎么在n+2次查找中找到答案呢?这个n+2很有深意哦~
思路如下:
第一次 问 300个a 得 q1
第二次 问 300个b 得 q2
想一想 N-q1是不是最终的a的个数 N-q2是不是最终的b的个数 总长度n=a+b
然后假设最终答案为 1个b加n-1个a ,此时如果真正的答案的第一个字符确实是b 那会返回b-1 否则返回b+1 通过这种区别来往后判断这个位置是b还是a
值得注意的是你写出的代码可能最多循环了n+3次 还需要特殊处理 见代码 不细说

#include
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ls k<<1,l,mid
#define rs k<<1|1,mid+1,r
#define r(x) read(x)
#define rrr(x, y, z) read(x);read(y);read(z)
#define mp(x, y) make_pair(x,y)
#define pb(x) push_back(x)
#define all(x) x.begin(),x.end()
#define FOR(i, l, r) for(int i=l;i<=r;i++)
using namespace std;

const int N = 1e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const int INF = 0x7fffffff;
const int SZ = 17;
const double eps = 1e-8;
const double PI = acos(-1);
typedef long long LL;
typedef pair<int, int> pt;

int n, m;
template<class T>
inline void read(T &x) {
    char c;
    x = 1;
    while ((c = getchar()) < '0' || c > '9') if (c == '-') x = -1;
    T res = c - '0';
    while ((c = getchar()) >= '0' && c <= '9') res = res * 10 + c - '0';
    x *= res;
}
int hhh(string s)
{
    cout<<s<<endl;
    int op;
    r(op);
    if(op==0) exit(0);
    return op;
}
int main() {
    int LEN=300;
    int rest=hhh(string(LEN,'a'));
    n=2*LEN-rest-hhh(string(LEN,'b'));
    int a=LEN-rest,b=n-a;
    string ans(n,'a');
    int tmp=b;
    for(int i=0;i<n-1;i++){
        ans[i]='b';
        if(hhh(ans)>tmp){
            ans[i]='a';
        }
        else tmp--;
    }
    if(tmp) ans[n-1]='b';
    hhh(ans);
    return 0;
}

你可能感兴趣的:(Contests,codeforces,div2,D,Artifact,Enchanted)