1. 程式人生 > >2017年“達內杯”臺州學院第十屆大學生程序設計競賽 非官方題解

2017年“達內杯”臺州學院第十屆大學生程序設計競賽 非官方題解

limit memory fff 這樣的 pac 接下來 dfs 字符串 begin

技術分享

感謝crq兄弟搞了這次校賽,讓我認識到了自己傻的時候確實傻的可愛。crq棒棒噠,我們OJ也十年多了,不容易啊。大家能用得上的時候確實要練好基本功啊。

5259: 多項式值統計 技術分享 技術分享

Time Limit(Common/Java):1000MS/3000MS Memory Limit:65536KByte
Total Submit: 316 Accepted:35

Description

形如anxn+an-1xn-1+…+a2x2 +a1x +a0的多項式稱為一元多項式,現給出若幹個一元多項式,以及x的值,請統計出:

(1)所有多項式的最大值;

(2)根據多項式值是否相同進行分組,相同值分為一組,不同值不同組,問組內多項式最多的組有多少個多項式?

Input

輸入數據有多組。

第一行為數據組數t。

接下來有t組數據,每組數據的第一行為兩個整數n(2<=n<=100)和x(絕對值不超過10),表示多項式的個數和多項式中x的取值。

接下來有n行,每行表示一個一元多項式,每個多項式先給出非零項的個數,再以指數遞降方式輸入一個多項式非零項系數(絕對值不超過10的整數)和指數(不超過10的非負整數)。

Output

每組輸出一行,包含兩個整數,分別為多項式的最大值和組內多項式最多的組所對應的多項式個數。

Sample Input

1
3 1
2 2 1 1 0
1 3 1
1 4 1

Sample Output

4 2

這道也是水題吧,求多項式的值,但是有個小細節,就是多項式的值可能是負數。map一下,建立鍵值就好了哇。

#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
int main()
{
    int t;
    while(cin>>t){
    while(t--){
       __int64 n,x;
       cin>>n>>x;
       __int64 ma1
=-1<<30; map<__int64,int>ma; while(n--){ __int64 m; cin>>m; __int64 ma2=0; for(__int64 i=0;i<m;i++){ __int64 a,b; cin>>a>>b; __int64 s=a; for(__int64 j=0;j<b;j++) s*=x; ma2+=s; } ma[ma2]++; ma1=max(ma2,ma1); } printf("%lld",ma1); map<__int64,int>::iterator it; int ma2=0; for(it=ma.begin();it!=ma.end();it++){ ma2=max(ma2,it->second); } printf(" %d\n",ma2); ma.clear(); }} return 0; }

5260: 排列 技術分享 技術分享

時間限制(普通/Java):1000MS/3000MS 內存限制:65536KByte
總提交: 83 測試通過:16

描述

從n個不同元素中任取m(m≤n)個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的一個排列。當m=n時所有的排列情況叫全排列。

比如有4個元素:1 3 4 6

其全排列為:

1 3 4 6

1 3 6 4

1 4 3 6

1 4 6 3

1 6 3 4

1 6 4 3

3 1 4 6

3 1 6 4

3 4 1 6

3 4 6 1

3 6 1 4

3 6 4 1

4 1 3 6

4 1 6 3

4 3 1 6

4 3 6 1

4 6 1 3

4 6 3 1

6 1 3 4

6 1 4 3

6 3 1 4

6 3 4 1

6 4 1 3

6 4 3 1

現在從中任選一個排列,比如

3 6 1 4

然後不斷地取下一個排列組成一個新的序列,當取到最後一個排列時重新回到第一個排列取,由此反復循環形成了一個無限長的序列:

3 6 1 4 3 6 4 1 4 1 3 6......

現在的問題是,這個序列的第x個元素是什麽?

輸入

輸入數據有多組(不大於100組),每組占2行,第一行為兩個正整數n和x,n和x的含義見描述(x<=1000000000,n<=5)。

接下來一行包含n個互不相同的正整數,表示全排列中任選的一個排列,並以此作為新序列的起始元素。

輸出

每組輸出一個正整數,表示第x個元素值。

樣例輸入

4 5
3 6 1 4

樣例輸出

3

第二題也是水題啊,自己一直錯,好氣哦,就是全排列找下第n個值啊,真是對自己無語了,那個我只進行了兩次就TLE真是醉了

#include <stdio.h>
#include <algorithm>
int has[100000];
using namespace std;
int main()
{int n,x;
while(~scanf("%d%d",&n,&x)){
    int b[10]={0};
    int a[10]={0};
    for(int i=1;i<=n;i++){
    scanf("%d",&a[i]);
    b[i]=a[i];}
    sort(b+1,b+n+1);
    int s1=0,f=0;
    int ac=0;
    int s=n;
    for(int i=2;i<=n;i++)
    s*=i;
    for(int i=0;i<s/n;i++){
    if(a[1]==b[1]&&a[2]==b[2]&&a[3]==b[3]&&a[4]==b[4])
    ac=1;
    else if(ac!=1)s1++;
    for(int j=1;j<=n;j++)
    has[f++]=b[j];
    next_permutation(b+1,b+n+1);}
    x=x+s1*n;
    x%=s;
    if(x!=0)x-=1;
    printf("%d\n",has[x]);
}
    
    return 0;
}

5263: 小朋友們的遊戲 技術分享 技術分享

時間限制(普通/Java):1000MS/3000MS 內存限制:65536KByte
總提交: 79 測試通過:7

描述

yuyu和小朋友們在操場上玩遊戲,互相之間需要通話,如果距離太遠,小朋友們就想辦法讓附近的人幫忙轉達一下。現在已知兩個小朋友之間直接通話所需要的音量等於他們之間距離的平方,問只要小朋友發出最少多大的音量就能保證互相之間都能夠通話。

輸入

輸入數據有多組,每組數據的第一行為正整數N(1<=N<=1000),表示小朋友的數量,接下來有N行,每行兩個整數x和y,表示小朋友所在的坐標值,坐標值絕對值小於25000。

輸出

每組輸出一個整數,表示所需要的音量。

樣例輸入

4
1 0
2 0
0 1
1 3

樣例輸出

5

最小生成樹,找到最長的權值,這個為什麽可以啊,我表示有點懵,當時沒帶模版,打不出來啊

#include<iostream>
using  namespace std;
#define MAX 1005
#define MAXCOST 0x7fffffff
int graph[MAX][MAX];
int x1[MAX],y1[MAX],mi;
int prim(int graph[][MAX], int n)
{
    int lowcost[MAX];
    int mst[MAX];
    int i, j, min, minid, sum = 0;
    for (i = 2; i <= n; i++)
    {
        lowcost[i] = graph[1][i];
        mst[i] = 1;
    }
    mst[1] = 0;
    for (i = 2; i <= n; i++)
    {
        min = MAXCOST;
        minid = 0;
        for (j = 2; j <= n; j++)
        {
            if (lowcost[j] < min && lowcost[j] != 0)
            {
                min = lowcost[j];
                minid = j;
            }
        }
        mi=max(mi,min);
        sum += min;
        lowcost[minid] = 0;
        for (j = 2; j <= n; j++)
        {
            if (graph[minid][j] < lowcost[j])
            {
                lowcost[j] = graph[minid][j];
                mst[j] = minid;
            }
        }
    }
    return mi;
}

int main()
{
    int i, j, k, l, m, n;
    int x, y, cost;
    while(cin >> n){
    mi=0;
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            graph[i][j] = MAXCOST;
        }
    }
    for(k = 1; k <= n; k++){
    cin>>x1[k]>>y1[k];
    for(l=1;l<k;l++)
    {
        cost=(x1[l]-x1[k])*(x1[l]-x1[k])+(y1[l]-y1[k])*(y1[l]-y1[k]);
        graph[k][l] = cost;
        graph[l][k] = cost;
    }
    }
    cost = prim(graph, n);
    cout <<mi << endl;}
    return 0;
}

5264: 買張公交卡吧 技術分享 技術分享

時間限制(普通/Java):1000MS/3000MS 內存限制:65536KByte
總提交: 408 測試通過:55

描述

crq是個無車一族,不過坐公交車可以打一個盹也不錯,最近聽說刷公交卡能打6折,還可以在1小時內免費換乘車1次(也就是在你上次刷卡付費後不超過1小時可以免費1次,但如果前一次免費則本次刷卡就不能免費了)。

現在給出crq一天以內的坐車情況,問這一天共消費了多少元。

假設公交車原價都是2元,而且每次都是刷卡消費,題目保證卡內余額充足。

輸入

輸入數據有多組,每組數據的第一行為正整數n(n<=10),表示乘坐的公交車趟數,接下來有n行,每行包括一個時間(格式hh:mm:ss),時間均在同一天內24小時制,而且已經按照時間先後排序。

輸出

每組輸出一個小數,表示總共消費金額,保留1位小數。

樣例輸入

3
12:00:00
12:30:00
12:50:00

樣例輸出

2.4

當時想了下背後的深層邏輯,好像我寫的最短啊.就是我標記下這次之前的有沒有享受一小時內換乘優惠

crq這個來源於生活啊,臺州公交是這樣的,臨海並不這樣啊

#include <stdio.h>
int main()
{int t;
while(~scanf("%d",&t)){
int h,m,s;
int sum=0,f=0,t2=0;    
while(t--){
   scanf("%d:%d:%d",&h,&m,&s);
   int t1=h*3600+m*60+s;
   if(t1-t2<=3600&&f==0){
       f=1;
   }
   else{
       sum+=2;
       f=0;
   }
   t2=t1;}
   printf("%.1f\n",sum*0.6);
}    
    return 0;
}

5265: 圍棋入門 技術分享 技術分享

時間限制(普通/Java):1000MS/3000MS 內存限制:65536KByte
總提交: 139 測試通過:22

描述

YuYu最近開始學習圍棋,爸爸先傳授她第一個入門基礎就是在哪些位置落子能夠將對方圍住。

現在給定棋盤某個狀態,輪到黑方落子(圍棋規定黑方先下,YuYu總是先下的),若要將白棋圍住,需要在哪些位置落子呢,請將它們全部找出來。

圍棋棋盤由19*19的方格組成,每個交叉點坐標為(i, j),其中1<=i<=19, 1<=j<=19。

技術分享

輸入

輸入數據有多組,每組數據包括19行,每行19個字符,其中:

(1).表示空白位置;

(2)B表示黑色棋子

(3)W表示白色棋子。

輸出

每組輸出若幹行,每行兩個正整數,表示可以落子的交叉點坐標值,按照行號從小到大的順序輸出,如果行號相同,則按照列號從小到大的順序輸出。

如果白方已經被圍住,輸出YuYu Wins!

樣例輸入

...................
...................
...................
...................
...................
........BW.........
...................
...................
...................
...................
...................
...................
...................
...................
...................
...................
...................
...................
...................

樣例輸出

5 10
6 11
7 10

沒想到這個題竟然是這種簡單的暴力,失策啊,bfs,dfs都試了的我,學長的思路更簡單啊,其實我代碼也可以很短了,刪了就不想再寫了

#include <iostream>
#include <string>
#include <cstring>
#include <queue>
using namespace std;
struct node{
    int x,y;
    bool friend operator <(node a,node b){
        if(a.x<b.x)
        return 1;
        else if(a.x==b.x&&a.y<b.y)
        return 1;
        return 0;
    }
}AC[400];
char s[20][20];
int vis[20][20];
int main(){
    memset(s,B,sizeof(s));
    while(~scanf("%s",s[1]+1)){
        memset(vis,1,sizeof(vis));
        for(int i=2;i<20;i++)
        cin>>s[i]+1;
        int f=0;
        for(int i=1;i<20;i++){
        for(int j=1;j<20;j++){
            if(s[i][j]==W){
            if(s[i+1][j]==.&&vis[i+1][j]){
                AC[f].x=i+1;
                AC[f++].y=j;
                s[i+1][j]==B;
                vis[i+1][j]=0;
            }
            if(s[i-1][j]==.&&vis[i-1][j]){
                AC[f].x=i-1;
                AC[f++].y=j;
                s[i-1][j]==B;
                vis[i-1][j]=0;
            }
            if(s[i][j+1]==.&&vis[i][j+1]){
                AC[f].x=i;
                AC[f++].y=j+1;
                s[i][j+1]==B;
                vis[i][j+1]=0;
            }
            if(s[i][j-1]==.&&vis[i][j-1]){
                AC[f].x=i;
                AC[f++].y=j-1;
                s[i][j-1]==B;
                vis[i][j-1]=0;
            }}
            
        }} 
        if(!f){printf("YuYu Wins!\n");
        continue;}
        sort(AC,AC+f);
        for(int i=0;i<f;i++)
        printf("%d %d\n",AC[i].x,AC[i].y);
        memset(s,B,sizeof(s));
    }
    return 0;
}

5266: 三角形相似 技術分享 技術分享

時間限制(普通/Java):1000MS/3000MS 內存限制:65536KByte
總提交: 299 測試通過:72

描述

給定兩個三角形的各條邊邊長,問這兩個三角形是否相似。

輸入

輸入數據有多組,每組有兩行,每行3個正整數,分別是兩個三角形的三條邊長(不超過100,數據保證滿足三角形條件)。

輸出

每組輸出一個“Yes”或者“No”,分別表示相似或者不相似。

樣例輸入

3 4 5
6 8 10

樣例輸出

Yes

忘記轉成浮點數的尷尬,錯了兩次吧,其實我那手速也不可能首A

#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
int main()
{
    int a[3],b[3];
    while(cin>>a[0]>>a[1]>>a[2]>>b[0]>>b[1]>>b[2]){
    sort(a,a+3);
    sort(b,b+3);
    int f=0;
    double c=a[0]*1.0/b[0];
    for(int i=1;i<3;i++){
        if(fabs(a[i]*1.0/b[i]-c)<1e-6)
        continue;
        else{
            puts("No");
            f=1;
            break;
            
        }
    }
    if(f==0)puts("Yes");}
    return 0;
}

5267: 卡片遊戲 技術分享 技術分享

時間限制(普通/Java):1000MS/3000MS 內存限制:65536KByte
總提交: 129 測試通過:14

描述

爸爸正在和YuYu玩一個卡片遊戲,共有N張卡片,每張卡片分別寫上1, 2, 3, ..., N數字,現在爸爸報出一個數字X,要求YuYu從中找出一段連續數字的卡片,使其和等於X。

如果有多個答案,爸爸要求卡片的數目越多越好。

YuYu還是一個二年級小朋友,現在她希望能求助於你!

輸入

輸入數據有多組(不超過50組),每組占一行,每行兩個整數N(1<=N<=10^8)和X(-10^9<=X<=10^9)。

輸出

每組輸出兩個數,表示卡片對應連續數字的第一個和最後一個的數字值,每組占一行,空格隔開, 如果答案不存在輸出“Error”。

樣例輸入

3 3
2 3
2 4

樣例輸出

1 2
1 2
Error

因式分解,自己手殘,用來測試的卻沒有改過來,GG

#include <stdio.h>
#include <math.h>
int main(){
int n,x;
while(~scanf("%d%d",&n,&x)){
    if(x<0){
        printf("Error\n");
        continue;
    }
    int f=1;
    x*=2;
    for(int i=sqrt(x);i;i--){
        if(x%i==0){
            int c=x/i;
            if((i+c)%2){
                int y=(i+c-1)/2;
                int e=c-y;
                if(y<=n&&e>0)
                {
                printf("%d %d\n",e,y);
                f=0;break;}
            }
        }
    }
    if(f)printf("Error\n");
}
return 0;}

5269: 瑪祖遊戲 技術分享 技術分享

時間限制(普通/Java):1000MS/3000MS 內存限制:65536KByte
總提交: 37 測試通過:12

描述

瑪祖是一款非常經典的遊戲,遊戲的角色是一只青蛙,青蛙每次可以吐出一顆珠子,如果將珠子吐到場景中相同顏色的珠子旁邊(稱為擊中),當三個或者三個以上的同顏色珠子在一起的時候便可以消掉,如果消掉後還有相同顏色的珠子,則可以繼續消除(我們稱為連擊)。

YuYu也很喜歡這個遊戲,而且希望連擊次數越多越好,因此每次當她發現擊中某種顏色的珠子能達到最大連擊次數時,她總是等待該顏色出現!

現在給定已經出現在遊戲場景中的珠子隊列,問瑜瑜可能達到的最大連擊次數是多少?

為了簡化問題,我們的遊戲規則是只要有兩個顏色相同的珠子連在一起都可以消掉。

技術分享

輸入

輸入數據有多組,每組占一行,每行一個由小寫字母組成的字符串,長度不超過100000,表示遊戲場景中的珠子隊列,每個字母代表一種顏色。

輸出

每組輸出一個數字,表示最大的連擊次數,該結果不會超過10000。

樣例輸入

b
aaabaaaa
ccccccccaaaaaaabbbdddddddeeeeeeeddddddbbbaaaaaaccccc

樣例輸出

1
2
5

現在我智商還是有問題的,一直少打了一個0,就是找最長回文串啊

#include <stdio.h>
char s[100005];
int main() {
    char c;
    while((s[0]=getchar())!=EOF) {
        int f=0,ma=1;
        while((c=getchar())!=\n){
            if(c!=s[f])
            s[++f]=c;
        }
        for(int i=1; i<f; i++) {
            int ans=1;
            int l=i-1,r=i+1;
            while(l>=0&&r<=f) {
                if(s[l]!=s[r])
                    break;
                l--;
                r++;
                ans++;
            }
            if(ans>ma)ma=ans;
        }
        printf("%d\n",ma);
    }
    return 0;
}

技術分享

2017年“達內杯”臺州學院第十屆大學生程序設計競賽 非官方題解