Codeforces Round #736 (Div. 2)

A. Gregor and Cryptography

题意:

题目给定一个≥5的质数 P P P,让你求出两个整数 a a a b b b,满足 P P P% a a a= P P P% b b b,且 a < b ≤ P a<b≤P a<bP

思路:

签到题, 没什么好说的,因为P是质数且P≥5,那么P肯定是个奇数,P%2肯定等于1,且P%(P-1)也肯定等于1,所以直接输出2和P-1即可。

代码:

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std; 
#define int long long
#define fi first
#define se second
#define endl '\n'
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
const int N=1e6+5;
int h[N],e[N],nx[N],idx;
int k,T,t,n,m,ans,cnt;
int a[N];
bool vis[N];
priority_queue <int,vector<int>,greater<int> > q;
signed main()
{
        ios::sync_with_stdio(false);
         cin.tie(0),cout.tie(0);
        cin>>T;
        while(T--)
        {
                int p,a,b;
                cin>>p;
                cout<<2<<" "<<p-1<<endl;
        }

        return 0;
}

B、Gregor and the Pawn Game

题意:

给定一个大小为 n ∗ n n*n nn的棋盘,给定两个字符串,第一个字符串代表敌方士兵,第二个字符串代表我方士兵,我方士兵位于最下一排,敌方士兵位于最上一排。敌方士兵不动,我方士兵可以向前移动(当其前方没有敌人),若其左前方或右前方有敌方士兵,则他可以斜着走,并把敌方士兵砍死。若字符串的i位置为1,代表当前这个位置有个士兵。让你判断有多少个我方士兵能到达最上方。

思路:

思路也不难想,我们从1~n开始遍历每个位置,若当前这个位置没有我方士兵,则continue。如果当前我方士兵 其左前方有敌方士兵,那么我们优先让我方士兵走左前方,因为这个左前方的位置肯定是其他我方士兵没有到达的(换句话说 就是前面的士兵可以到达这个位置,但是由于他也优先选了左或前,所以这个位置空了下来),若左前方不能走,我们再去判断前方,若前方没有敌方士兵,则可以向前,因为此时无论是在左或是右的我方士兵,都到达不了这个点。(其实优先走中再走左也是可以的),最后再判断能不能走右前方,若能走就走。(我们很容易知道,虽然往右前方走可能会影响后一个士兵向左走,但是一定不会使答案变差)

代码:

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std; 
#define int long long
#define fi first
#define se second
#define endl '\n'
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
const int N=1e6+5;
int h[N],e[N],nx[N],idx;
int k,T,t,n,m,ans,cnt;
int a[N];
char s1[N],s2[N];
bool vis[N];
priority_queue <int,vector<int>,greater<int> > q;
signed main()
{
        ios::sync_with_stdio(false);
         cin.tie(0),cout.tie(0);
        cin>>T;
        while(T--)
        {
                cin>>n;
                cin>>s1+1>>s2+1;
                int ans=0,res=0;
                s1[0]='0';
                s1[n+1]='0';
                for(int i=1;i<=n;i++)
                {
                        if(s2[i]=='0') continue;
                        if(s1[i]=='0') ans++;
                        else if(s1[i-1]=='1')
                        {
                                ans++;
                                s1[i-1]='2';
                        }
                        else if(s1[i+1]=='1')
                        {
                                ans++;
                                s1[i+1]='2';
                        }
                }
                cout<<ans<<endl;
        }

        return 0;
}

C. Web of Lies

题意:

给定n个人,以及m个好友关系,然后接下来m次,让给定的两个人成为朋友。如果一个人有朋友,并且他朋友比他强,那他当场去世。接着给定操作次数q,每次操作有三种,当op为1时,让给定的两个人成为朋友。当op为2时,删除某两个人之间的好友关系。当op为3时,查询有多少人还活着。(!!!!!注意每次查询是独立的!!!!!即当前查询完某些人死了,下次查询相当于这些人原地复活,然后再重新查询,这个点非常关键)

思路:

这题的坑点就是每次查询是独立的,读题如果没注意到这个点就吃大亏了,我就读了半小时假题。我们注意到每个人如果有朋友并且比他强就会把他杀了,那么其实我们只要定义一个数组,记录每个人的朋友 比他强的个数有多少个就行了。一开始我们先把m个关系加上,然后判断此时有多少活人。之后进行操作时,因为先前的关系是还在的,该死了的肯定死了,不需要重新计算的。
具体来说,如果此时操作为1,那么就是将两个人定义为朋友,也就是通过这个操作,会让弱的那个人的 比他强的朋友的个数加1。如果他之前没有比他更强的朋友,那他经过这个操作之后,就会去世了,即答案减1,反之若其有比他更强的朋友,那他早就被砍死了,现在多出来一个砍他的丝毫不影响他的去世(可能只是死的更惨了点hh)。
如果此时操作为2,即删除了两个人的好友关系,也就是让弱的那个人的 比他强的朋友的个数减1,倘若此时 比他强的好友个数为0了,则相当于现在没人杀他了,那么此时活人就多了一个,即让答案加1.
若操作为3时,我们直接输出当前的答案即可。

代码:

#include<bits/stdc++.h>
//#pragma GCC optimize(2)
using namespace std; 
#define int long long
#define fi first
#define se second
#define endl '\n'
#define PII pair<int,int>
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
const int N=1e6+5;
int h[N],e[N],nx[N],idx;
int k,T,t,n,m,ans,cnt;
int a[N];
bool vis[N];
priority_queue <int,vector<int>,greater<int> > q;
signed main()
{
        ios::sync_with_stdio(false);
         cin.tie(0),cout.tie(0);
        cin>>n>>m;
        int ans=n;
        for(int i=1;i<=m;i++)
        {
                int x,y;
                cin>>x>>y;
                if(x>y) a[y]++;
                else a[x]++;
        }
        for(int i=1;i<=n;i++) if(a[i]>0) ans--;
        cin>>T;
        while(T--)
        {
                int op,x,y;
                cin>>op;
                if(op==1)
                {
                        cin>>x>>y;
                        if(x>y)
                        {
                                if(!a[y]) ans--;
                                a[y]++;
                        }        
                        else
                        {
                                if(!a[x]) ans--;
                                a[x]++;        
                        }                
                }        
                else if(op==2)
                {
                        cin>>x>>y;
                        if(x>y)
                        {
                                a[y]--;        
                                if(!a[y]) ans++; 
                        }
                        else
                        {
                                a[x]--;        
                                if(!a[x]) ans++;
                        }
                }
                else cout<<ans<<endl;
        }
        return 0;
}

D. Integers Have Friends

D待补。。好像可以用线段树过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值