first

CodeForces - 879A  div-3

考贪心的一个题,刚开始理解有点误差,题目说要按顺序拜访医生,所以要先拜访完第一个医生再拜访第二个医生,刚开始以为是看哪个医生最先有空就去拜访哪个,就以为是个排序题,看了半小时才看出来是个贪心,由于必须【按顺序见医生】,所以要在当前应该见的医生的工作日中,选择一个大于见上一个医生的时间的最小时间(贪心思想),更新答案即可。

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 1010;

int n,sum = 0;
int s,d;

int main()
{
    cin >> n;
    for(int i = 0;i < n;i ++ )
    {
        cin >> s >> d;
        
        while(sum >= s) s += d;//注意是while不是if
        
        sum = s;
    } 
    cout << sum << endl;
    return 0;
}

 

 

CodeForces - 879B div-3

题意:

一排人打乒乓球,力量大的总能赢,打输或打平那么这个人到队尾,当一个人连赢k次之后结束

题解:

开始看到队首和队尾还以为是个队列题,最后才看出来就是个模拟。思路就是第一个人开始打,把第一个人看作一个指针,如果能打过,赢的次数加一,指针往后走,如果没打过x这个人,由于第一个人没打过x,所以x赢的初始的次数为1,指针继续往后走,以此类推,当某个人连续赢了k次或指针移动到了n时结束,因为当指针移动到n时表示这一排人没人能打过这个人了,不论k有多大这个人最终都能到,所以到n直接输出就可以。

#include <iostream>
#include <algorithm>

using namespace std;

int n;
long long k,cnt = 0;
int power[510];

int main()
{
    cin >> n >> k;
    for(int i = 0; i < n;i ++ ) cin >> power[i];
    
    int ans = power[0];
    for(int i = 1 ;i < n;i ++ )
    {
        if(cnt == k)
        {
            cout << ans << endl;
            return 0;
        }
        if(ans > power[i])
        {
            cnt++;
        }
        
        else
        {
            ans = power[i];
            cnt = 1;
        }
    }
    cout << ans << endl;
    return 0;
}

 

 

CodeForces - 879C   div-2

题目的意思是,先给出一个n,然后紧接着跟着n行的程序,每一行含有一个操作符和一个操作数,操作符只有三种与,或,异或。同时规定所有的操作数都在0-1023之间。

要你把给出的程序缩短,缩短到5行之内。
思路:要你把程序缩短,因为只有三种操作符,那么显然所有的程序的结果都可以通过这三种操作符得到,那么我们只需要规定最后的输出一定是是三个,然后我们要做的就是求解三种操作符之后的操作数。因为要使得程序的结果相同,而且所有的操作数都在0-1023之间,那么我们可以将所有的操作对这10位二进制的数的影响记录下来。
其中或‘ | ’ ,很显然,一位1或上不论或上任何数字都是本身 ,所以这一位上的值是可以确定的。
同理与‘&’ ,很显然,与会和或相反,也就是0于上任何一个数字都是本身,那么这一位也是可以确定的。
如果程序遇到了异或‘^’  ,因为假如这一位上是1,那么遇上异或可能是1和0,如果是1和1那么这一位上就会是0,如果是0那么这一位上就不会改变。如果是0,那么遇上1,就会变成1,遇上0,那么就还是0;所以我们可以总结出,如果程序遇上异或,那么该位上的数值就要变成相反的数,也就是0-1,1-0;那么就要把所有位取反。
经过所有的操作符和操作数的影响,最后可以得出一个10位的影响数。
那么接下来就是把各个操作数取出来了,因为如果一位上是1,那么它可以通过或确定
那么先算或的,那么我们就可以加起来就好了,也就是把这一位上是1的加起来就是,或的操作数。
然后是与的,因为与确定的是0的位,那么我们就用一个初始值全部为1的初值来得出,也就是减去记录下来的10位数值。
最后是异或,这个更简单,直接或一下得出答案就好。

一位数的位运算:

  “&”: 0&0=0,0&1=0,1&0=0,1&1=1;

  “|”: 0|0=0,0|1=1,1|0=1,1|1=1;

  “^”: 0^0=0,0^1=1,1^0=1,1^1=0。

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
 
int main(void)
{
    int n;
    int x = 0, y = 1023;//y最大为1023
    cin >> n;
    for (int i = 0; i < n; i ++ ) 
    {
        getchar();//吃掉回车 
        char op = getchar();
        int num;
        cin >> num;
        switch (op)
        {
            case '&':
            x &= num;
            y &= num;
            break;
            case '|':
            x |= num;
            y |= num;
            break;
            case '^':
            x ^= num;
            y ^= num;
            break;
            default:
            break;
        }
    }
    int num_and = x | y,
        num_or = x & y,
        num_xor = x & (1023 ^ y);
    printf("3\n& %d\n| %d\n^ %d\n", num_and, num_or, num_xor);
    return 0;
} 

 

 

也可以bitset暴力

然鹅我还没学过

 

总结:算是正儿八经的第一次训练,结果前两个题都差点没做出来,后三个题都没有学过,看都看不懂。。。哭辽。。。。。算是知道我现在有多菜了。。。

posted @ 2021-01-26 10:56  彦辰kkkkk  阅读(143)  评论(0)    收藏  举报