题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805064676261888
分析:这题看起来非常唬人,其实不难。。。。。四个judge基本没啥差,就是输入稍微注意一下,只要知道怎么构造一个堆是非常水的一道题目
堆的话就是二叉树,儿子的值一定不小于父亲的值,左子树是父亲节点的2倍,右子树是父亲节点2倍+1
用的是向上浮动的方法构造,听大牛说“必须注意,因为题目要求按照插入的顺序建立,所以是边插入边调整的,必须用向上调整,每次输入一个数之后就将它向上调整。(两者建立出来的二叉树不同)而不能采用先转换为二叉树的方式再向下调整。”
不过具体原因我也不知道。。。。。
上代码吧
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int inf=1<<30; 5 const double pi=acos(-1); 6 const int mod=998244353; 7 const int maxn=1050; 8 const int maxm=6300; 9 int a[maxn];int n,m; 10 void upadjust(int i){ 11 if(i==1)return ; 12 while(i!=1){ 13 if(a[i]<a[i/2]){ 14 swap(a[i],a[i/2]); 15 i/=2; 16 }else{ 17 break; 18 } 19 } 20 } 21 void judge1(int x){ 22 if(a[1]==x)printf("T\n"); 23 else printf("F\n"); 24 } 25 void judge2(int x,int y){ 26 int idxa,idxb; 27 for(int i=1;i<=n;i++){ 28 if(a[i]==x)idxa=i; 29 if(a[i]==y)idxb=i; 30 } 31 if(idxa>idxb) swap(idxa,idxb);//保证左边的是a,接下来好判断 32 if(idxa%2==0&&idxb-idxa==1)printf("T\n"); 33 else printf("F\n"); 34 } 35 void judge3(int x,int y){ 36 int idxa,idxb; 37 for(int i=1;i<=n;i++){ 38 if(a[i]==x)idxa=i; 39 if(a[i]==y)idxb=i; 40 } 41 if(idxa*2==idxb||idxa*2==idxb-1)printf("T\n"); 42 else printf("F\n"); 43 } 44 void judge4(int x,int y){ 45 int idxa,idxb; 46 for(int i=1;i<=n;i++){ 47 if(a[i]==x)idxa=i; 48 if(a[i]==y)idxb=i; 49 } 50 if(idxb*2==idxa||idxb*2==idxa-1)printf("T\n"); 51 else printf("F\n"); 52 } 53 int main(){ 54 scanf("%d%d",&n,&m); 55 for(int i=1;i<=n;i++){ 56 scanf("%d",&a[i]); 57 upadjust(i); 58 } 59 char c[100]; 60 int x,y; 61 for(int i=0;i<m;i++){ 62 scanf("%d%s",&x,c); 63 if(strcmp(c,"and")==0){ 64 scanf("%d%s%s",&y,c,c); 65 judge2(x,y); 66 } 67 else{ 68 scanf("%s",c); 69 if(strcmp(c,"a")==0){ 70 scanf("%s%s%d",c,c,&y); 71 judge4(x,y); 72 } 73 else { 74 scanf("%s",c); 75 if(strcmp(c,"root")==0){ 76 judge1(x); 77 } 78 else{ 79 scanf("%s%d",c,&y); 80 judge3(x,y); 81 } 82 } 83 } 84 } 85 return 0; 86 }