周赛(一)——题目整理

2018/4/1

基础题:

欢迎使用信阳师范学院在线评测(Online Judge)平台!

问题 A: 寻找第二小的数

时间限制: 1 Sec   内存限制: 32 MB
提交: 16   解决: 11
[ 提交][ 状态][ 讨论版]

题目描述

求n个整数中第二小的数。
相同的整数看成一个数。比如,有5个数分别是1,1,3,4,5,那么第二小的数就是3。

输入

输入包含多组测试数据。输入的第一行是一个整数C,表示有C组测试数据;
每组测试数据的第一行是一个整数n,表示本组测试数据有n个整数(2<=n<=10),接着一行是n个整数(每个数均小于100)。

输出

为每组测试数据输出第二小的整数,如果不存在第二小的整数则输出“NO”,每组输出占一行。

样例输入

3
2
1 2
5
1 1 3 4 5
3
1 1 1

样例输出

2
3
NO

提示

入门题


# include<stdio.h>
# include<algorithm>
using namespace std;
int main(){
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int a[105];
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
        int m,k=0;
        sort(a,a+n);
        m=a[0];
        for(int i=1;i<n;i++)
        {
            if(a[i]>m)
            {
                k=1;
                printf("%d\n",a[i]);
                break;
            }
        }
        if(!k) printf("NO\n");
    }
     
    return 0;
}

问题 F: 混合数列

时间限制: 1 Sec   内存限制: 128 MB
提交: 10   解决: 9
[ 提交][ 状态][ 讨论版]

题目描述

请输出一个数列:

该数列包含两个数列,数列1:a(n)=a(n-2)+2*n,数列2:b(n)=b(n-2)*2+1。

手动输入a(1)与b(2),且a(1),b(2)均为大于零的正整数。

合成数列为由数列a与数列b交替组成,输出合成数列前20位。

输入

输入有多组样例。

输入两个整数,a[1] 和b[2]。

输出

输出这个序列(注意每行末尾没有空格)

样例输入

1 4
9 9

样例输出

1 4 7 9 17 19 31 39 49 79 71 159 97 319 127 639 161 1279 199 2559
9 9 15 19 25 39 39 79 57 159 79 319 105 639 135 1279 169 2559 207 5119

提示

假如数列a为1,2,3,4,5 b为,6,7,8,9,10,即合成数列的前5位为1,7,3,9,5


题目智能推荐
#include<stdio.h>
int main()
{
    int a,b,num[30];
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        num[1]=a;num[2]=b;
        for(int i=3;i<=20;i++)
        {
            if(i%2)//奇数
            num[i]=num[i-2]+2*i;
            else
            num[i]=num[i-2]*2+1;
        }
        for(int i=1;i<20;i++)
        printf("%d ",num[i]);
        printf("%d\n",num[20]);
    }
}
 

搜索:

问题 B: 数独

时间限制: 1 Sec   内存限制: 64 MB
提交: 23   解决: 19
[ 提交][ 状态][ 讨论版]

题目描述

  数独是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个3*3宫内的数字均含1-9,不重复。 每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。

  有一天hrdv碰到了一道号称是世界上最难的数独的题目,作为一名合格的程序员,哪能随随便便向困难低头,于是他决定编个程序来解决它。。


输入

第一行有一个数n(0< n <100),表示有n组测试数据,每组测试数据是由一个9*9的九宫格构成,0表示对应的格子为空

输出

输出一个9*9的九宫格,为这个数独的答案

样例输入

1
0 0 5 3 0 0 0 0 0
8 0 0 0 0 0 0 2 0
0 7 0 0 1 0 5 0 0
4 0 0 0 0 5 3 0 0
0 1 0 0 7 0 0 0 6
0 0 3 2 0 0 0 8 0
0 6 0 5 0 0 0 0 9
0 0 4 0 0 0 0 3 0
0 0 0 0 0 9 7 0 0

样例输出

1 4 5 3 2 7 6 9 8 
8 3 9 6 5 4 1 2 7 
6 7 2 9 1 8 5 4 3 
4 9 6 1 8 5 3 7 2 
2 1 8 4 7 3 9 5 6 
7 5 3 2 9 6 4 8 1 
3 6 7 5 4 2 8 1 9 
9 8 4 7 6 1 2 3 5 
5 2 1 8 3 9 7 6 4 

提示

#include<stdio.h>
#include<string.h>
int map[9][10];
bool row[9][10],col[9][10];
bool black[3][3][10];
int flag,i,j,t;
void dfs(int x)
{
    int r,c,k;
    r=x/9;
    c=x%9;
    if(flag)
    {
        return;
    }
    if(x==81)
    {
        for(i=0;i<9;i++)
           for(j=0;j<9;j++)
             if(j<8)
             printf("%d ",map[i][j]);
             else printf("%d\n",map[i][j]);
        flag=1;
        return;      
    }
    if(!map[r][c])
    for(k=1;k<=9;k++)
    {
        if(row[r][k]==0&&col[c][k]==0&&black[r/3][c/3][k]==0)
        {
            map[r][c]=k;
            row[r][k]=col[c][k]=black[r/3][c/3][k]=1;
            dfs(x+1);
            row[r][k]=col[c][k]=black[r/3][c/3][k]=0;
            map[r][c]=0;
        }
    }
    else
    dfs(x+1);
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        flag=0;
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));
        memset(black,0,sizeof(black));
        for(i=0;i<9;i++)
          for(j=0;j<9;j++)
          {
            scanf("%d",&map[i][j]);
            if(map[i][j])
            {
                row[i][map[i][j]]=1;
                col[j][map[i][j]]=1;
                black[i/3][j/3][map[i][j]]=1;
              }
          }
          dfs(0);
    }
}

问题 G: Oil Deposit

时间限制: 1 Sec   内存限制: 32 MB
提交: 27   解决: 13
[ 提交][ 状态][ 讨论版]

题目描述

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.

输入

The input file contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.

输出

For each grid, output the number of distinct oil deposits. Two different pockets are part of the same oil deposit if they are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.

样例输入

3 4
**@*
*@*@
@***
4 5
@**@@
*@**@
@**@*
@**@@
0 3

样例输出

1
2

提示


#include<stdio.h>
#include<string.h>
char map[150][150];
int vis[150][150];
int n,m;
 
int dir[8][2]={1,0,-1,0,0,1,0,-1,1,1,1,-1,-1,1,-1,-1};

void dfs(int x,int y)
{
    int tx,ty;
    for(int i=0;i<8;i++)
    {
        tx=x+dir[i][0];
        ty=y+dir[i][1];
        if(tx>=0&&tx<n&&ty>=0&&ty<m&&!vis[tx][ty]&&map[tx][ty]=='@')
        {
            vis[tx][ty]=1;
            dfs(tx,ty);
        }
    }
}
 
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF&&n)
    {
        for(int i=0;i<n;i++)
        scanf("%s",map[i]);
        memset(vis,0,sizeof(vis));
        int ans=0;
         
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(!vis[i][j]&&map[i][j]=='@')
                ans++,dfs(i,j);     
            }
        }
        printf("%d\n",ans);
    }   
    return 0;
}
 

欢迎使用信阳师范学院在线评测(Online Judge)平台!

问题 I: 迷宫寻宝(一)

时间限制: 1 Sec   内存限制: 64 MB
提交: 39   解决: 13
[ 提交][ 状态][ 讨论版]

题目描述

一个叫ACM的寻宝者找到了一个藏宝图,它根据藏宝图找到了一个迷宫,这是一个很特别的迷宫,迷宫里有N个编过号的门(N<=5),它们分别被编号为A,B,C,D,E.为了找到宝藏,ACM必须打开门,但是,开门之前必须在迷宫里找到这个打开这个门所需的所有钥匙(每个门都至少有一把钥匙),例如:现在A门有三把钥匙,ACM就必须找全三把钥匙才能打开A门。现在请你编写一个程序来告诉ACM,他能不能顺利的得到宝藏。

输入

输入可能会有多组测试数据(不超过10组)。
每组测试数据的第一行包含了两个整数M,N(1<N,M<20),分别代表了迷宫的行和列。接下来的M每行有N个字符,描述了迷宫的布局。其中每个字符的含义如下:
.表示可以走的路
S:表示ACM的出发点
G表示宝藏的位置
X表示这里有墙,ACM无法进入或者穿过。
A,B,C,D,E表示这里是门,a,b,c,d,e表示对应大写字母的门上的钥匙。
注意ACM只能在迷宫里向上下左右四个方向移动。

最后,输入0 0表示输入结束。

输出

每行输出一个YES表示ACM能找到宝藏,输出NO表示ACM找不到宝藏。

样例输入

4 4
S.X.
a.X.
..XG
....
3 4
S.Xa
.aXB
b.AG
0 0

样例输出

YES 
NO

提示

题目智能推荐
# include<stdio.h>  
# include<queue>  
# include<string.h>  
using namespace std;  
int b[4][2]={0,1,1,0,-1,0,0,-1};//上下左右四个方向   
char a1[25][25];  
int v[25][25];//标记走过的路   
int n,m,k1[6],k2[6],s1,s2,k;  
struct node{  
    int x,y;      
};  
int dfs()  
{     
k=0;  
memset(v,0,sizeof(v));  
    queue<node>s;  
    node p,q;   
    p.x=s1;  
    p.y=s2;  
    s.push(p); v[s1][s2]=1;  
    while(!s.empty())  
    {  
    p=s.front();  
        s.pop();   
        if(a1[p.x][p.y]=='G')//如果找到宝箱   
        return 1;  
        for(int i=0;i<4;i++)  
        {  
            q.x=p.x+b[i][0];  
            q.y=p.y+b[i][1];  
            if(q.x>=0&&q.x<n&&q.y>=0&&q.y<m&&a1[q.x][q.y]>='a'&&a1[q.x][q.y]<='e')  
            {    k2[a1[q.x][q.y]-'a']++;  
            a1[q.x][q.y]='.';  
            k=1;//找到钥匙   
            }  
            if(q.x>=0&&q.x<n&&q.y>=0&&q.y<m&&!v[q.x][q.y]&&a1[q.x][q.y]!='X')  
            {  
                if(a1[q.x][q.y]>='A'&&a1[q.x][q.y]<='E')  
                {  
                    if(k2[a1[q.x][q.y]-'A']==k1[a1[q.x][q.y]-'A'])//找到的钥匙数与总共的钥匙数的关系   
                    {                    //如果相等这开门;   
                        s.push(q);  
                    v[q.x][q.y]=1;  
                    }  
                }  
                else {  
                s.push(q);  
                    v[q.x][q.y]=1;                    
                }  
            }  
                               
        }     
    }  
 if(!k)    return -1;  //如果没找到钥匙   
else return 0;     //找到钥匙但没找到宝箱   
       
}  
int main(){  
    while(~scanf("%d%d",&n,&m)&&m&&n)  
    {  getchar();  
        int i,j;  
        memset(k1,0,sizeof(k1));  
        memset(k2,0,sizeof(k2));  
          
    for(i=0;i<n;i++)   
        {  
            scanf("%s",&a1[i]);  
            for(j=0;j<m;j++)  
            if(a1[i][j]>='a'&&a1[i][j]<='e')  
            k1[a1[i][j]-'a']++;  
            else if(a1[i][j]=='S'){  
            s1=i;s2=j;    
            }  
            getchar();  
        }  
        while(1)//每次都重新调用函数   
        {  
            int w=dfs();  
            if(w==1)  {  //如果返回值为1 说明已经找到宝箱   
                printf("YES\n");  
                break;  
            }  
            else if(w==-1)  // 如果没有找到钥匙并且没有找到 宝箱 则说明不可能成功   
            {  
                printf("NO\n");break;  
            }  
          }    
    }  
       
    return 0;  
}  

贪心:

问题 E: BUYING FEED

时间限制: 3 Sec  内存限制: 64 MB
提交: 6  解决: 4
[ 提交][ 状态][ 讨论版]

题目描述

Farmer John needs to travel to town to pick up K (1 <= K <= 100)pounds of feed. Driving D miles with K pounds of feed in his truck costs D*K cents.

The county feed lot has N (1 <= N<= 100) stores (conveniently numbered 1..N) that sell feed. Each store is located on a segment of the X axis whose length is E (1 <= E <= 350). Store i is at location X_i (0 < X_i < E) on the number line and can sell John as much as F_i (1 <= F_i <= 100) pounds of feed at a cost of C_i (1 <= C_i <= 1,000,000) cents per pound.
Amazingly, a given point on  the X axis might have more than one store.

Farmer John  starts  at location 0 on this number line and can drive only in the positive direction, ultimately arriving at location E, with at least K pounds of feed. He can stop at any of the feed stores along the way and buy any amount of feed up to the the store's limit.  What is the minimum amount Farmer John has to pay to buy and transport the K pounds of feed? Farmer John
knows there is a solution. Consider a sample where Farmer John  needs two pounds of feed from three stores (locations: 1, 3, and 4) on a number line whose range is 0..5:     
0   1   2  3   4   5    
---------------------------------         
1           1   1                Available pounds of feed         
1           2   2               Cents per pound

It is best for John to buy one pound of feed from both the second and third stores. He must pay two cents to buy each pound of feed for a total cost of 4. When John travels from 3 to 4 he is moving 1 unit of length and he has 1 pound of feed so he must pay1*1 = 1 cents.

When John travels from 4 to 5 heis moving one unit and he has 2 pounds of feed so he must pay 1*2 = 2 cents. The total cost is 4+1+2 = 7 cents.

输入

The first line of input contains a number c giving the number of cases that follow There are multi test cases ending with EOF. Each case starts with a line containing three space-separated integers: K, E, and N Then N lines follow :every line contains three space-separated integers: Xi Fi Ci

输出

For each case,Output A single integer that is the minimum cost for FJ to buy and transport the feed

样例输入

12 5 3                 3 1 24 1 21 1 1

样例输出

7

提示

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
using namespace std;
struct node{
    int xi,fi,ci;
    int sum;
}a[105];
int cmp(node x,node y)
{
    if(x.sum==y.sum)
        return x.fi>y.fi;
    else
        return x.sum<y.sum;
}
int main()
{
    int k,e,n;
    int test;
    scanf("%d",&test);
    while(test--)
    {
        scanf("%d%d%d",&k,&e,&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d",&a[i].xi,&a[i].fi,&a[i].ci);
            a[i].sum=a[i].ci+abs(e-a[i].xi);
        }
        sort(a,a+n,cmp);
        int ans=0;
        for(int i=0;i<n&&k>0;i++)
        {
            if(k>a[i].fi){
                ans+=a[i].fi*a[i].sum;
                k-=a[i].fi;
            }
            else{
                ans+=k*a[i].sum;
                break;
            }
        }
        printf("%d\n",ans);
     } 
     
}
字符串处理:
欢迎使用信阳师范学院在线评测(Online Judge)平台!

问题 D: 幂次方分解

时间限制: 1 Sec   内存限制: 128 MB
提交: 6   解决: 5
[ 提交][ 状态][ 讨论版]

题目描述

任何一个正整数都可以用2的幂次方表示。例如:
137=2^7+2^3+2^0
同时约定方次用括号来表示,即a^b 可表示为a(b)。
由此可知,137可表示为:
2(7)+2(3)+2(0)
进一步:7= 2^2+2+2^0 (2^1用2表示)
3=2+2^0
所以最后137可表示为:
2(2(2)+2+2(0))+2(2+2(0))+2(0)
又如:
1315=2^10 +2^8 +2^5 +2+1
所以1315最后可表示为:
2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

输入

输入包含一个正整数N(N<=20000),为要求分解的整数。

输出

程序输出包含一行字符串,为符合约定的n的0,2表示(在表示中不能有空格)

样例输入

1315

样例输出

2(2(2+2(0))+2)+2(2(2+2(0)))+2(2(2)+2(0))+2+2(0)

提示

蓝桥杯练习题(新)-算法训练


题目智能推荐

[ 提交][ 状态]

#include<stdio.h>
#include<string.h>
int n,flag,num[16];
int b[16]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
 
int main()
{
     
    char a[16][30];
    strcpy(a[0],"2(0)");//给字符串复制不能直接写等于,C语言用strcpy 
    strcpy(a[1],"2");     
    strcpy(a[2],"2(2)");
    strcpy(a[3],"2(2+2(0))");
    strcpy(a[4],"2(2(2))");
    strcpy(a[5],"2(2(2)+2(0))");
    strcpy(a[6],"2(2(2)+2)");
    strcpy(a[7],"2(2(2)+2+2(0))");
    strcpy(a[8],"2(2(2+2(0)))");
    strcpy(a[9],"2(2(2+2(0))+2(0))");
    strcpy(a[10],"2(2(2+2(0))+2)");
    strcpy(a[11],"2(2(2+2(0))+2+2(0))");
    strcpy(a[12],"2(2(2+2(0))+2(2))");
    strcpy(a[13],"2(2(2+2(0))+2(2)+2(0))");
    strcpy(a[14],"2(2(2+2(0))+2(2)+2)");
    strcpy(a[15],"2(2(2+2(0))+2(2)+2+2(0))");
    while(scanf("%d",&n)!=EOF)
    {
        memset(num,0,sizeof(num));
        flag=0;
        for(int i=15;i>=0;i--)
        {
            if(n>=b[i])
            {
                num[flag++]=i;
                n-=b[i];
            }
        }
        for(int i=0;i<flag-1;i++)
        {
            printf("%s+",a[num[i]]);
        }
        printf("%s\n",a[num[flag-1]]);  
    }
 
    return 0;
}

图论(+dfs):

问题 J: 成语接龙

时间限制: 1 Sec   内存限制: 32 MB
提交: 11   解决: 5
[ 提交][ 状态][ 讨论版]

题目描述

小明在玩成语接龙的游戏。成语接龙的规则是,如果成语A的最后一个汉字与成语B的第一个汉字相同,那么成语B就可以接到成语A的后面。
小明现在手上有一本成语词典,每次他都得花费一定时间来从当前的成语查到下一个可以接在后面的成语。
现在给你一个成语列表,请你计算从列表中的第一个成语开始,到接到列表中的最后一个成语最少需要多长时间。

输入

输入包含多组测试数据。
每组输入第一行是一个整数N(0<N<1000),表示成语列表的长度。
接下来N行,每行先输入一个整数T,再输入一个字符串S。
S表示一条成语,T表示小明从S查到下一个成语所花费的时间。
每条成语由至少3个汉字组成,每个汉字由4个十六进制数(0~9和A~F)组成。
当N=0时,输入结束。

输出

对于每组输入,输出从列表中的第一个成语开始,到接到列表中的最后一个成语需要的最少时间。
如果无法连接到列表中的最后一个成语,则输出-1。

样例输入

5
5 12345978ABCD2341
5 23415608ACBD3412
7 34125678AEFD4123
15 23415673ACC34123
4 41235673FBCD2156
2
20 12345678ABCD
30 DCBF5432167D
0

样例输出

17
-1

提示

入门题-图论


#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;
#define inf 0x3f3f3f3f
int ans,n;
int vis[1005];
struct node{
    int time;
    char s[10];
    char e[10];
}a[1005];
void dfs(int k,int sum){
    if(strcmp(a[k].e,a[n-1].s)==0){
        //sum+=a[n-1].time;
        if(sum<ans){
            ans=sum;
            return;
        }
    }
    for(int i=1;i<n-1;i++){
        if(!vis[i]&&strcmp(a[k].e,a[i].s)==0){
            vis[i]=1;
            dfs(i,sum+a[i].time);
            vis[i]=0;
        }
    }
}
int main()
{
//  int n;
    while(~scanf("%d",&n)&&n){
        ans=inf;
        //string str;
        if(n==1){
            printf("0\n");
            continue;
        }
        memset(vis,0,sizeof(vis));
        for(int i=0;i<n;i++)
        {
            char str[1000];
            scanf("%d %s",&a[i].time,str);
            int len=strlen(str);
            a[i].s[0]=str[0];
            a[i].e[0]=str[len-4];
            a[i].s[1]=str[1];
            a[i].e[1]=str[len-4+1];
            a[i].s[2]=str[2];
            a[i].e[2]=str[len-4+2];
            a[i].s[3]=str[3];
            a[i].e[3]=str[len-4+3];
        }
        vis[0]=1;
        dfs(0,a[0].time);
        if(ans==inf)
        printf("-1\n");
        else
        printf("%d\n",ans);
    }
}

动态规划:

01背包

问题 H: 点菜问题

时间限制: 1 Sec   内存限制: 32 MB
提交: 15   解决: 10
[ 提交][ 状态][ 讨论版]

题目描述

北大网络实验室经常有活动需要叫外买,但是每次叫外买的报销经费的总额最大为C元,有N种菜可以点,经过长时间的点菜,网络实验室对于每种菜i都有一个量化的评价分数(表示这个菜可口程度),为Vi,每种菜的价格为Pi, 问如何选择各种菜,使得在报销额度范围内能使点到的菜的总评价分数最大。
    注意:由于需要营养多样化,每种菜只能点一次。

输入

输入的第一行有两个整数C(1 <= C <= 1000)和N(1 <= N <= 100),C代表总共能够报销的额度,N>代表能点菜的数目。接下来的N行每行包括两个在1到100之间(包括1和100)的的整数,分别表示菜的价格和菜的评价分数。

输出

输出只包括一行,这一行只包含一个整数,表示在报销额度范围内,所点的菜得到的最大评价分数。

样例输入

1 3
1 5
3 3
2 5
24 8
2 9
8 6
4 1
1 4
2 2
10 5
2 1
1 4

样例输出

5
30

提示

#include<stdio.h>
#include<string.h>
using namespace std;
struct Node{
    int c,p;
     
}node[1005];
int max(int a,int b){
    return a>b?a:b;
}
int  main(){
    int cc,n;
    int dp[1005];
    while(scanf("%d%d",&cc,&n)!=EOF){
        int sum=0;
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++){
            scanf("%d%d",&node[i].c,&node[i].p);
        }
        for(int i=0;i<n;i++){
            for(int j=cc;j>=node[i].c;j--){
                dp[j]=max(dp[j],dp[j-node[i].c]+node[i].p);
            }
        }
         
        printf("%d\n",dp[cc]);
    }
    return 0;
}

这道题没有做出来;开始的时候当成贪心做了,测试数据都没过。后来才知道用动态规划(听队友说这道题类似于:导弹拦截)。

问题 C: 猴子与香蕉

时间限制: 1 Sec   内存限制: 32 MB
提交: 13   解决: 7
[ 提交][ 状态][ 讨论版]

题目描述

一组研究人员正在设计一个测试猴子IQ的实验。他们把香蕉吊在屋顶上,同时给猴子提供了砖块。如果猴子够聪明,它会把砖块一个个叠起来做成一个塔,然后爬上去拿到自己喜爱的食物。
研究人员有n种不同的砖块,而且每种砖块都是取之不尽的。每种砖块都是长方体,第i种砖块的大小是(xi,yi,zi)。砖块能够翻转,可以将任意两边当作底面,剩下的那边作为高。
他们想确定用砖块搭成的最高塔,能否帮助猴子够着屋顶。问题是,在叠塔过程中,要放的那块砖,其底面两条边都要小于下面那块砖的两条边,这是为了留个空间给猴子踩脚。
例如,底面相同尺寸的砖块不能相叠。
现给定砖块,请计算猴子能够叠塔的最大高度。

输入

输入包含多组测试数据。每组输入的第一行是一个整数n,表示砖块的种类数。n的最大值是30。
接着n行,每行输入三个整数xi,yi和zi。
当n=0时,输入结束。

输出

对于每组输入,输出一行:测试例编号case(从1开始编号),塔能够达到的最大高度height。
输出格式为:“Case case: maximum height = height”。

样例输入

1
10 20 30
2
6 8 10
5 5 5
7
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
5
31 41 59
26 53 58
97 93 23
84 62 64
33 83 27
0

样例输出

Case 1: maximum height = 40
Case 2: maximum height = 21
Case 3: maximum height = 28
Case 4: maximum height = 342
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node{
	int le,w,h;
}a[100005];
long long dp[100005];
bool cmp(node x,node y)
{
	if(x.w<y.w)return 1;
	if(x.w==y.w&&x.le<y.le) return 1;
	if(x.w==y.w&&x.le==y.le&&x.h>y.h) return 1;
	return 0;//一定要加返回值 
} 
int main()
{
	int n,k=1;
	while(~scanf("%d",&n)&&n)
	{
		int c[3],l=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d%d%d",&c[0],&c[1],&c[2]);
			sort(c,c+3);//有三种情况,且宽一定小于高 
			a[l].w=c[0];a[l].le=c[1];a[l].h=c[2];
			l++;
			a[l].w=c[1];a[l].le=c[2];a[l].h=c[0];
			l++;
			a[l].w=c[0];a[l].le=c[2];a[l].h=c[1];
			l++;
		}
		sort(a,a+l,cmp);
		memset(dp,0,sizeof(dp)); 
		//核心代码
		dp[0]=a[0].h;
		long long maxx=a[0].h;
		for(int i=1;i<l;i++) 
		{
			for(int j=0;j<i;j++)
			{
				if(a[i].le>a[j].le&&a[i].w>a[j].w&&dp[i]<dp[j])
				{
					dp[i]=dp[j];
				}
			}
			dp[i]+=a[i].h;
			if(dp[i]>maxx)maxx=dp[i];
		}
		printf("Case %d: maximum height = %lld\n",k++,maxx);	
	}
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值