noip2007普及組T1--T4題解

T1:獎學金

Description

  某小學最近得到了一筆贊助,打算拿出其中一部分爲學習成績優秀的前5名學生髮獎學金。期末,每個學生都有3門課的成績:語文、數學、英語。先按總分從高到低排序,如果兩個同學總分相同,再按語文成績從高到低排序,如果兩個同學總分和語文成績都相同,那麼規定學號小的同學排在前面,這樣,每個學生的排序是唯一確定的。

    任務:先根據輸入的3門課的成績計算總分,然後按上述規則排序,最後按排名順序輸出前5名學生的學號和總分。注意,在前5名同學中,每個人的獎學金都不相同,因此,你必須嚴格按上述規則排序。例如,在某個正確答案中,如果前兩行的輸出數據(每行輸出兩個數:學號、總分)是:

    7  279

    5  279

    這兩行數據的含義是:總分最高的兩個同學的學號依次是7號、5號。這兩名同學的總分都是279(總分等於輸入的語文、數學、英語三科成績之和),但學號爲7的學生語文成績更高一些。如果你的前兩名的輸出數據是:

    5  279

    7  279

    則按輸出錯誤處理,不能得分。 

Input

  輸入包含n+1行:

    第l行爲一個正整數n,表示該校參加評選的學生人數。

    第2到年n+l行,每行有3個用空格隔開的數字,每個數字都在0到100之間。第j行的3個數字依次表示學號爲j-1的學生的語文、數學、英語的成績。每個學生的學號按照輸入順序編號爲1~n(恰好是輸入數據的行號減1)。

    所給的數據都是正確的,不必檢驗。 

Output

  輸出共有5行,每行是兩個用空格隔開的正整數,依次表示前5名學生的學號和總分。 

Sample Input

Sample 1:
6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
Sample 2:
8
80 89 89
88 98 78
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98

Sample Output

Sample 1:
6 265
4 264
3 258
2 244
1 237
Sample 2:
8 265
2 264
6 264
1 258
5 258

HINT

50%的數據滿足:各學生的總成績各不相同  100%的數據滿足:6< =n< =300 

此題爲水題,T1不想解釋

#include<stdio.h>
int main()
{
    int i,j,k,n,yu[301],shu[301],ying[301],zong[301],id[301],t;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d",&yu[i],&shu[i],&ying[i]);
        zong[i]=yu[i]+shu[i]+ying[i];
        id[i]=i;
    }
    for(i=1;i<=n;i++)
    {
        for(j=2;j<=n;j++)
        {
           if(zong[i]<zong[j]&&i<j)
           {
           t=yu[j];
           yu[j]=yu[i];
           yu[i]=t;    
           t=zong[j];
           zong[j]=zong[i];
           zong[i]=t;
           t=id[j];
           id[j]=id[i];
           id[i]=t;
           }
           else if(zong[j]==zong[i]&&i<j)
           {
               if(yu[i]<yu[j])
               {
                   t=yu[j];
                   yu[j]=yu[i];
                   yu[i]=t;
                  t=id[j];
                  id[j]=id[i];
                  id[i]=t;
               }
               else if(yu[i]==yu[j]&&i!=j)
               {
                   if(id[i]>id[j])
                   {
                    t=id[j];
                  id[j]=id[i];
                  id[i]=t;
                   }
               }
           }
        }
    }
    for(i=1;i<6;i++)
    {
        printf("%d %d\n",id[i],zong[i]);
    }
}
T2:紀念品分組

Description

元旦快到了,校學生會讓樂樂負責新年晚會的紀念品發放工作。

爲使得參加晚會的同學所獲得的紀念品價值相對均衡,他要把購來的紀念品根據價格進行分組,但每組最多隻能包括兩件紀念品,  並且每組紀念品的價格之和不能超過一個給定的整數。

爲了保證在儘量短的時間內發完所有紀念品,樂樂希望分組的數目最少。 

你的任務是寫一個程序,找出所有分組方案中分組數最少的一種,輸出最少的分組數目。

【限制】

  50%的數據滿足:  1  < =n  < =  15

  100%的數據滿足:  1  < =  n  < =  30000,  80  < =  W  < =  200   

Input

第1行包括一個整數w,爲每組紀念品價格之和的上限=

第2行爲一個整數n,表示購來的紀念品的總件數G

第3-n+2行每行包含一個正整數Pi  (5  < =  Pi  < =  w3) w表示所對應紀念品的價格。 

Output

僅1行,包含一個整數,  ep最少的分組數目合 

Sample Input

100
9
90
20
20
30
50
60
70
80
90

Sample Output

6

先排序,前後左端點與右端點一起找儘量兩兩一組。

#include<algorithm>
using namespace std;
#include<stdio.h>
int a[30001];
int main()
{
	int x,n,ans=0,i;
	scanf("%d%d",&x,&n);
	for(i=1;i<=n;i++)
	   scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    int q=1,r=n;
    while(q<=r)
    {
    	if(a[q]+a[r]<=x)
		{
			q++;
			r--;
		}
    	else r--;
    	ans++;
    }
    if(q==r)
		ans++;
    printf("%d",ans);
}
T3:守望者的逃離

Description

        惡魔獵手尤迪安野心勃勃,他背叛了暗夜精靈,率領深藏在海底的娜迦族企圖叛變。守望者 在與尤迪安的交鋒中遭遇了圍殺,被困在一個荒蕪的大島上。爲了殺死守望者,尤迪安開始對這 個荒島施咒,這座島很快就會沉下去。到那時,島上的所有人都會遇難。守望者的跑步速度爲 17m/s,以這樣的速度是無法逃離荒島的。慶幸的是守望者擁有閃爍法術,可在1s內移動60m,不 過每次使用閃爍法術都會消耗魔法值10點。守望者的魔法值恢復的速度爲4點/s,只有處在原地 休息狀態時才能恢復。

        現在已知守望者的魔法初值M,他所在的初始位置與島的出口之間的距離S,島沉沒的時間T。 你的任務寫寫一個程序幫助守望者計算如何在最短的時間內逃離荒島,若不能逃出,則輸出守望 者在剩下的時間能走的最遠距離。注意:守望者跑步、閃爍或休息活動均以秒(s)爲單位,且每 次活動的持續時間爲整數秒。距離的單位爲米(m)。

Input

在輸入僅一行,包括空格隔開的三個非負整數M,S,T。

Output

在輸出包括兩行:

  第1行爲字符串“Yes”或“No”(區分大小寫),即守望者是否能逃離荒島。

  第2行包含一個整數。第一行爲“Yes”(區分大小寫)時表示守望者逃離荒島的最短時間; 第一行爲“No”(區分大小寫)時表示守望者能走的最遠距離。

Sample Input

【輸入樣例1】
39 200 4
【輸入樣例2】
36 255 10

Sample Output

【輸出樣例1】
No
197
【輸出樣例2】
Yes
6

HINT

30%的數據滿足:1< =T< =10,1< =S< =100

50%的數據滿足:1< =T< =1000,1< =S< =10000 

100%的數據滿足:1< =T< =300000,0< =M< =1000,1< =S< =108

貪心,也可以DP

#include<stdio.h>
int main() 
{
	int m,s,t;
 	int i,x,y; 
  	scanf("%d%d%d",&m,&s,&t);
   	x=y=0;
    for(i=1;i<=t;i++) 
	{
 		if(m>=10) 
		{
  			x+=60; 
  			m-=10;
    	       } 
		else 
  		m+=4;
         if(x>y+17) 
		 y=x;
         else 
		 y+=17;
         if(y>=s) 
		 break;
     }
     if(i>t) 
	 	printf("No\n%d",y);
     else 
	 	printf("Yes\n%d",i);
}

Description

        給定A,B,C三根足夠長的細柱,在A柱上放有2n箇中間有孔的圓盤,共有n個不同的尺寸,每個尺寸都有兩個相同的圓盤,注意這兩個圓盤是不加區分的。現要將這些圓盤移到C柱上,在移動過程中可放在B柱上暫存。要求:  

 

 (1)每次只能移動一個圓盤;    (2)  A、B、C三根細柱上的圓盤都要保持上小下大的順序;    任務:設An爲2n個圓盤完成上述任務所需的最少移動次數,對於輸入的n,輸出An。

Input

輸入爲一個正整數n,表示在A柱上放有2n個圓盤。

Output

僅一行,包含一個正整數,爲完成上述任務所需的最少移動次數An。

Sample Input

Sample 1:
1
Sample 2:
2

Sample Output

Sample 1:
2
Sample 2:
6

HINT

對於50%的數據,  1< =n< =25

對於100%  數據,  1< =n< =200   

這道題基本是T4最水的題了,答案是2的n+1次冪-2
#include<stdio.h>
int f[201]={0,1};
int main()
{
	int n,i,j,x;
	scanf("%d",&n);
	for(i=1;i<=n+1;i++)
	{
		for(j=1;j<=n+1;j++)
		{
			f[j]=f[j]*2;
		}
		for(j=1;j<=n+1;j++)
		{
			if(f[j]>=10)
			{
				f[j+1]+=f[j]/10;
				f[j]=f[j]%10;
			}
		}
	}
	f[1]=f[1]-2;
	if(f[1]<0)
	{
		f[2]-=1;
		f[1]+=10;
	}
	for(i=n+1;i>0;i--)
	{
		if(f[i]!=0)
		{
			x=i;
			break;
		}
	}
	for(i=x;i>0;i--)
		printf("%d",f[i]);
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章