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 }
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 }
C题:Make Good
首先这个题我一开始想的话,想法肯定是先把第一个加起来得到一个sum1,那么把第二个加起来得到一个sum2
(1):两个数
我想一下怎么好操作呢,我先把sum2给变成0,只有变成0以后才好操作,这样的话第一个就变成了sum+sum2,第二个变成了0,那么我们接下来就很好操作了,直接算上第二个数sum1+sum2即可
(怎么才能想到这个做法啊??????????????????????????????????????????????????????????????????????)
我一开始想的是一种做法是正面突破,感觉一点都不美啊,这个做法就很沙雕
我觉得这个题我们如果要知道这样做的话,得知道的一点是我们要把他看作一个构造题。这样的话我们就好做了。
_________________________________________________________________________________________
然后我们考虑先把后面的东东变成特殊的东东,比如变成0,从特殊到一般,这样就很好搞了
我觉得这应该是核心应该要了解的一个点???????
————————————————————————————————————————————
这个题怎么做呢????
这个想法要怎么得出来?
我昨天晚上感觉智商受到了封印,我的想法一直都在乱想,感觉想的就按照直接怎么做去了,我想置换出来后就没想了,虽然这样正面是很难做出的,就很迷
真正的做法是:我们先假设一个我们先把前面的数假设排好序,我们不一定要把前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 }
————————————————————————————————————————————————————
(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 }