Goodbye 2019

A题:Card Game

这道题挺简单,谁最大谁就能赢!

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <bitset>
 5 #include <cstdio>
 6 typedef long long ll;
 7 using namespace std;
 8 int n,k1,k2,t;
 9 int main(){
10     scanf("%d",&t);
11     while(t--){
12         scanf("%d%d%d",&n,&k1,&k2);
13         int flag=0;
14         for(int i=1;i<=k1;i++){
15             int a;
16             scanf("%d",&a);
17             if(a==n) flag=1;
18         }
19         for(int i=1;i<=k2;i++){
20             int a;
21             scanf("%d",&a);
22         }
23         if(flag) printf("YES\n");
24         else printf("NO\n");
25     }
26     return 0;
27 }
View Code

 

 

B题:Interesting Subarray

我们首先知道如果某个段可行的话,    那么可以知道的事是max(s)-min(s)>=l;

假设所有的i都不满足abs(ai[i+1]-ai[i])>=2的话,那就没有办法了,肯定是输出No,其他就输出就ok

下面是代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <bitset>
 5 #include <cstdio>
 6 typedef long long ll;
 7 using namespace std;
 8 const int maxn=(int)(2e5+100);
 9 int t,n;
10 ll num[maxn];
11 
12 int main(){
13     scanf("%d",&t);
14     while(t--){
15         scanf("%d",&n);
16         for(int i=1;i<=n;i++) scanf("%lld",&num[i]);
17         //以l为最小值 ,
18         //  2 3 4 5
19         
20         int flag=0;
21         for(int i=1;i<n;i++){
22             if(max(num[i+1],num[i])-min(num[i+1],num[i])>1){
23                 printf("YES\n");
24                 printf("%d %d\n",i,i+1);
25                 flag=1;
26                 break;
27             }
28         }
29         if(flag==0) printf("NO\n");
30     }
31     return 0;
32 }
View Code

 

C题:Make Good

首先这个题我一开始想的话,想法肯定是先把第一个加起来得到一个sum1,那么把第二个加起来得到一个sum2

(1):两个数

我想一下怎么好操作呢,我先把sum2给变成0,只有变成0以后才好操作,这样的话第一个就变成了sum+sum2,第二个变成了0,那么我们接下来就很好操作了,直接算上第二个数sum1+sum2即可

 

 

(怎么才能想到这个做法啊??????????????????????????????????????????????????????????????????????)

我一开始想的是一种做法是正面突破,感觉一点都不美啊,这个做法就很沙雕

我觉得这个题我们如果要知道这样做的话,得知道的一点是我们要把他看作一个构造题。这样的话我们就好做了。

 

_________________________________________________________________________________________

然后我们考虑先把后面的东东变成特殊的东东,比如变成0,从特殊到一般,这样就很好搞了

我觉得这应该是核心应该要了解的一个点???????

————————————————————————————————————————————

 

D题:Strange Device

这个题怎么做呢????

这个想法要怎么得出来?

我昨天晚上感觉智商受到了封印,我的想法一直都在乱想,感觉想的就按照直接怎么做去了,我想置换出来后就没想了,虽然这样正面是很难做出的,就很迷

 

真正的做法是:我们先假设一个我们先把前面的数假设排好序,我们不一定要把前n个取完,只取前k+1个就可以了。扯到过多的变量会什么没用的也会被

带入进来。

我们假设取了小于m的数不取,那么肯定我们取得是ai[m+1]大的数,而我们大于等于m的数不取,我们取得是ai[m]的数

只会出现两个变量,而且前一个变量只会出现m次,我们只要记录一下最大的那个变量出现的次数就是m的值了

下面是代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <map>
 8 typedef long long ll;
 9 using namespace std;
10 int n,k,p,v,mx=0;
11 map<int,int> mp;
12 int main(){
13     scanf("%d%d",&n,&k);
14     for(int i=1;i<=k+1;i++){
15         printf("?");
16         for(int j=1;j<=k+1;j++){
17             if(i==j) continue;
18             printf(" %d",j);
19         }
20         printf("\n");
21         fflush(stdout);
22         scanf("%d%d",&p,&v);
23         mp[v]++;
24         mx=max(mx,v);
25     }
26     printf("! %d\n",mp[mx]);
27     return 0;
28 }
View Code

 

————————————————————————————————————————————————————

(1):首先,如果能少用变量,就不要多用变量,引入更多变量会变得很麻烦

  (2):   很多时候一定要记得及时引入特例,这样是最重要的,把一个变量变成特别的,或者从特别的样例来看,这样是

最重要,而且最好的。 

(3):不要围绕一些东西硬想,我们要学会转换,比如一些问题可以转换成另外一个问题。

————————————————————————————————————————————————————

(4):我们一开始要知道的事我们先把这个排序好,建立一个顺序是很重要的,这个是解题的关键

  (6):   还有就是引入前k+1的概念

(5):只要排好序后,我们就很好的思考了,这样的东西就是假设取m个以前的和m个以后的,这样就很搞了。。。

————————————————————————————————————————————————————

________________________________________________________________________________________________________

 

 

E题: Divide Points

这个题是真的不错的,我一直在想啥并查集,二分图啥的的图论做法,然后最后发现这TM是个构造?????????

——————————————————————————————————————————————————————————

这个构造是利用奇偶性质的,这我确实没有想到,是真的妙

怎么想到奇偶构造呢????????????????这是个大问题,我们从那个方面开始想,去想?

能想到这个奇偶构造?

分成两边呢?

我一直在想并查集和二分图,然后就陷入进去了

——————————————————————————————————————————————————————————

按奇偶分类,如果一开始能进入奇偶分类的思维,那么这个题就基本入了道了

但是怎么进入这个思维呢???????????????????????

我看见别人的代码,总是一下子就能想到正解?

————————————————————————————————————————————————————————————

我觉得把坐标分成几类应该可以看作是一种套路下次,记得就ok了

————————————————————————————————————————————————————————————

下面有个讲解:来源https://www.cnblogs.com/19992147orz/p/12120059.html

下面是截图:

 

 

然后是代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <cmath>
 6 #include <bitset>
 7 #include <vector>
 8 typedef long long ll;
 9 using namespace std;
10 const int maxn=(int)(2e5+100);
11 int n;
12 int x[maxn],y[maxn],cnt[2][2];
13 int main(){
14     scanf("%d",&n);
15     for(int i=1;i<=n;i++){scanf("%d%d",&x[i],&y[i]);}
16     while(1){
17         int s=0;
18         memset(cnt,0,sizeof(cnt));
19         for(int i=1;i<=n;i++){
20             ++cnt[x[i]&1][y[i]&1];
21         }
22         vector<int> ans;
23         if(cnt[0][0]+cnt[1][1]>0&&cnt[0][1]+cnt[1][0]>0){
24             for(int i=1;i<=n;i++){
25                 if((x[i]+y[i])%2==0){
26                     ans.push_back(i);
27                 }
28             }
29             printf("%d\n",(int)ans.size());
30             for(int i=0;i<ans.size();i++){
31                 printf("%d  ",ans[i]);
32             }
33             printf("\n");break;
34         }
35 
36         if(cnt[0][0]+cnt[0][1]>0&&cnt[1][1]+cnt[1][0]>0){
37             for(int i=1;i<=n;i++){
38                 if((x[i])%2==0){
39                     ans.push_back(i);
40                 }
41             }
42             printf("%d\n",(int)ans.size());
43             for(int i=0;i<ans.size();i++){
44                 printf("%d  ",ans[i]);
45             }
46             printf("\n");break;
47         }
48 
49         for(int i=1;i<=n;i++){
50             x[i]=x[i]>>1;
51             y[i]=y[i]>>1;
52 
53         }
54     }
55     return 0;
56 }
View Code

posted on 2019-12-31 00:38  pandaking  阅读(173)  评论(0编辑  收藏  举报

导航