zoukankan      html  css  js  c++  java
  • csp-M4-C-宇宙狗的危机

    题意描述

    在瑞神大战宇宙射线中我们了解到了宇宙狗的厉害之处,虽然宇宙狗凶神恶煞,但是宇宙狗有一个很可爱的女朋友。

    最近,他的女朋友得到了一些数,同时,她还很喜欢树,所以她打算把得到的数拼成一颗树。

    这一天,她快拼完了,同时她和好友相约假期出去玩。贪吃的宇宙狗不小心把树的树枝都吃掉了。所以恐惧包围了宇宙狗,他现在要恢复整棵树,但是它只知道这棵树是一颗二叉搜索树,同时任意树边相连的两个节点的gcd(greatest common divisor)都超过1。

    但是宇宙狗只会发射宇宙射线,他来请求你的帮助,问你能否帮他解决这个问题。

    补充知识:

    GCD:最大公约数,两个或多个整数共有约数中最大的一个 ,例如8和6的最大公约数是2。

    一个简短的用辗转相除法求gcd的例子:

    int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}

    输入
    输入第一行一个t,表示数据组数。

    对于每组数据,第一行输入一个n,表示数的个数

    接下来一行有n个数​,输入保证是升序的。

    输出
    每组数据输出一行,如果能够造出来满足题目描述的树,输出Yes,否则输出No。
    无行末空格。

    输入样例 1

    1
    6
    3 6 9 18 36 108
    1
    2
    3
    输出样例 1

    Yes
    1
    输入样例 2

    2
    2
    7 17
    9
    4 8 10 12 15 18 33 44 81
    1
    2
    3
    4
    5
    输出样例2

    No
    Yes

    思路:

    dp构建可行二叉搜索树!

    所有的数据都是有序的,可以考虑区间dp。to_l[i][j]代表[i,j-1]是否可作为j的左子树。to_r[i][j]表示[i+1,j]是否可以作为i的右子树。

    转移条件为:if (GCD[l-1][root]>1)R[l-1][r]=1; if (GCD[r+1][root]>1)L[l][r+1]=1;

    当[l,r]为[1,n]时说明可以构建符合题意的树,如果枚举结束都到不了[1,n]说明不可以构建符合题意的树。GCD数组记录两点gcd.

    初始化时注意将 to_l[i][i]和to_r[i][i]都赋值为1,因为当点i的左子树或者右子树为空时一定是符合题意的

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 const int maxn=770;
     5 int n,t;
     6 int a[maxn],GCD[maxn][maxn] ;
     7 bool to_l[maxn][maxn],to_r[maxn][maxn];
     8 
     9 int gcd(int a,int b){ 
    10     return b == 0 ? a : gcd(b,a%b);
    11 }
    12 bool solve()
    13 {
    14     for(int len=1;len<=n;len++)
    15         {
    16             for(int l=1;l<=n-len+1;l++)
    17             {
    18                 int r=l+len-1;
    19                 for(int k=l;k<=r;k++)
    20                 {
    21                     if(to_l[k][l] && to_r[k][r])
    22                     {
    23                         if(len==n)
    24                         {
    25                             return true; 
    26                         }
    27                         if(GCD[l-1][k] > 1) 
    28                             to_r[l-1][r]=1;
    29                         if(GCD[k][r+1] > 1) 
    30                             to_l[r+1][l]=1; 
    31                     }
    32                 }
    33             }
    34         }
    35         return false;
    36 }
    37 void init(){
    38     memset(to_l,0,sizeof(to_l));
    39     memset(to_r,0,sizeof(to_r));    
    40     for(int i=1;i<=n;i++)
    41         {
    42             for(int j=i;j<=n;j++)
    43             {
    44                 
    45                 GCD[j][i]=gcd(a[i],a[j]);
    46                 GCD[i][j]=GCD[j][i];
    47             }
    48             to_l[i][i]=1;
    49             to_r[i][i]=1;            
    50         }                
    51 }
    52 int main()
    53 {
    54     cin>>t;
    55     while(t--)
    56     {
    57         //input 
    58         cin>>n;
    59         for(int i=1;i<=n;i++)
    60             cin>>a[i];            
    61         //initialize  
    62         init();
    63         //solve
    64         bool flag = solve();
    65         if(flag){
    66             cout<<"Yes"<<endl;
    67         }
    68         else cout<<"No"<<endl;
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    css实现京东顶部导航条
    css盒布局-省份选择盘的实现
    css字体的属性
    css行高
    CSS定位(position)
    CSS-clear属性的作用
    2.b统计字符串长度
    rectangle类。java
    mysql 版本问题之sql-mode 导致 sql 语句报错
    根据一个表中同一字段的不同值进行统计!!!
  • 原文地址:https://www.cnblogs.com/liuzhuan-xingyun/p/13049068.html
Copyright © 2011-2022 走看看