1. 程式人生 > >第三屆全國中醫藥院校大學生程式設計競賽 (正式賽)

第三屆全國中醫藥院校大學生程式設計競賽 (正式賽)

 Problem B. 綠地裝飾(暴力模擬+思維)

時間限制: 1  記憶體限制: 128 MB

提交: 56  解決: 22  201501010119

提交狀態討論版

題目連結:http://acm.hnucm.edu.cn/JudgeOnline/problem.php?id=1366

題目描述

湖南中醫藥大學坐落於中國歷史文化名城長沙,是湖南省重點建設本科院校,是全國首批設立國家級重
點學科的高校,也是首批招收博士研究生、留學生及港澳臺學生的中醫藥院校。學校現有 2 個校區,佔
地面積 1393 畝,建築面積 52 萬平方米,主校區依嶽麓南坡,臨湘江西岸,環境幽雅,風光秀麗,是求
學成才的理想之地。
校園景觀設計師小 W 的主要工作就是植被環境的設計維護,他有一個 N×N 的模板圖,他創作景觀的步
驟如下:
1、將當前的綠地分成 N×N 小塊,再按照模板圖新增裝飾(黑色表示有裝飾,白色表示沒有);
2、對於每個白色(未被裝飾)的地塊,遞迴操作 1,應用模板圖,即分成更小的 N×N 塊,繼續進行裝
飾,而黑色(已裝飾)的地塊則不必操作。

下圖是某次裝飾過程的示意圖。

現在你的任務是求出 K 次遞迴後的綠地狀態。

輸入

單組資料。
第一行兩個數 N,K,如題意中的描述。
接下來是一個 N×N 的模板圖,’ . ’ 表示白色,’ * ’ 表示黑色。
2 ≤ n ≤ 3
1 ≤ k ≤ 5

 

輸出

輸出一個 N K×N K 的矩陣表示答案,不允許有多餘的空行或空格。

樣例輸入

2 3
.*
..

樣例輸出

.*******
..******
.*.*****
....****
.***.***
..**..**
.*.*.*.*
........

【分析】資料很小,暴力模擬。注意一下細節要。定義一個二維字元陣列做中轉

【程式碼】

#include<bits/stdc++.h>
using namespace std;

const int maxn=300;
char mp[maxn][maxn];//最終圖 
char s[maxn][maxn];//中間圖 
char s0[5][5];//原始模板 

int n,k;

int main()
{
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)scanf("%s",s0[i]);
	int side=1;
	mp[0][0]='.';
	while(k--)
	{
		for(int i=0;i<side;i++)
			for(int j=0;j<side;j++)
			{
				if(mp[i][j]=='.')
					for(int p=0;p<n;p++)
						for(int q=0;q<n;q++)
							s[i*n+p][j*n+q]=s0[p][q];
				else
				for(int p=0;p<n;p++)
						for(int q=0;q<n;q++)
							s[i*n+p][j*n+q]='*';
			}
		side*=n;
		for(int i=0;i<side;i++)
			for(int j=0;j<side;j++)
				mp[i][j]=s[i][j];
	}
	for(int i=0;i<side;i++)printf("%s\n",mp[i]);
	return 0;
}

E 解密(水+有點巧妙的解法)

時間限制: 1  記憶體限制: 128 MB

提交: 109  解決: 59  201501010119

提交狀態討論版

題目描述

湖南中醫藥大學有含浦、東塘 2 個校區,學校辦學歷史悠久,前身為 1934 年的湖南國醫專科學校,1953
年創辦湖南中醫進修學校,1960 年建立普通高等本科院校——湖南中醫學院,1979 年成為全國首批取得
中醫類研究生學歷教育資格的院校,1990 年原湖南科技大學成建制併入湖南中醫學院,2002 年與湖南省
中醫藥研究院合併,2006 年經教育部批准更名為湖南中醫藥大學,2012 年進入湖南省一本招生序列。
目前,學校與湖南省中醫藥研究院實行校院合一的管理體制。學校學科門類齊全、中醫藥特色鮮明。學校
設有 18 個學院、24 個本科專業,涵蓋醫、理、工、管、文等 5 大學科門類。中醫診斷學在本學科研究領
域居國內領先水平。
小 F 居住在含浦校區,他想和東塘校區的同學小 L 聊天,為了保證溝通安全,他發明了一種加密方式,這
種加密方式是這樣的:對於一個 01 串,小 F 會將其從左到右每 8 位分成一組,最後一組可能不足 8 位,
對每組進行逆序操作,即如果原來是 bLbL+1bL+2 · · · bR−1bR, 逆序之後變成 bRbR−1bR−2 · · · bL−1bL。現在
小 F 已經加密好了一個串,並且將其發給了小 L,你能幫助小 L 得到這串密文對應的原始資訊嗎?

輸入

單組資料。
一行一個 01 串,代表加密後的字串,串長度大於 0, 小於等於 100。

輸出

一行字串,代表加密後的字串所對應的原始信。

樣例輸入

100010110011101

樣例輸出

110100011011100

【題意】字串8個一組逆序輸出。不足8個的也要逆序

【分析】水題啦,不過看了標程之後發現程式碼可以很簡潔思維可以很巧妙!

【程式碼】

#include<bits/stdc++.h>
using namespace std;
 
char s[105];
 
int main()
{
    scanf("%s",s);
    int len=strlen(s);
    for(int i=0;i<len;i+=8)
    {
        int l=i,r=min(len-1,i+7);
        while(l<r)
        {
            swap(s[l],s[r]);
            l++;r--;
        }
    }
    puts(s);
}

H: 百舸爭流(貪心)

時間限制: 1  記憶體限制: 128 MB

提交: 80  解決: 13  201501010119

提交狀態討論版

題目連結:http://acm.hnucm.edu.cn/JudgeOnline/problem.php?id=1372

題目描述

橘子洲風景區位於湖南省長沙市市區對面的湘江江心,是湘江中最大的名洲,由南至北,橫貫江心,西望
嶽麓山,東臨長沙城,四面環水,綿延數十里,狹處橫約 40 米,寬處橫約 140 米,形狀是一個長島,是
國家重點風景名勝區。
一天,N 名選手參加了一年一度的橘洲競渡大賽,現在只剩下最後一場決賽了!
賽制為積分制,N 名選手的積分分別為 A1 到 AN。決賽的積分規則如下:第一名得 B1 分,第二名得 B2
分,……,第 m 名得 Bm 分,第 m+1 名至第 n 名不得分。最後第 i 名選手的總得分為 Ai 加上他在決
賽中的得分。
我們按總分為第一關鍵字、名字的字典序為第二關鍵字對選手進行排序。現告訴你一名選手的名字,希望
你告訴他,他最終的排名最前可能是多少,最後可能是多少。

輸入

單組資料。
第一行為一個數 n,表示有 n 名選手 (1 ≤ n ≤ 105)。

接下來有 n 行,每行由一個字串 S 和一個非負整數 Ai 表示,代表該人的名字和決賽之前的總分。

(名字僅由英文字母和數字表示,長度不超過 20,沒有相同名字的兩個人,0 ≤ Ai ≤ 106)。

接下來一個數 m(0 ≤ m ≤ n)。
接下來一行 m 個數字依次表示 B1, B2, B3, · · · , Bm (0 ≤ Bi ≤ 106)。
最後一個字串表示詢問的選手的名字。

輸出

輸出兩個數,第一個表示最終排名最前可能多少,第二個表示最後可能多少。

樣例輸入

3
CH1 10
CH2 20
CH3 40
2
20 10
CH1

樣例輸出

2 3

【題意】給出n個人的分數以及最後一場的前m名可以加分的分數,詢問其中一位選手的最終排名的最好名次和最差名次。

【分析】先把n個人的分數和最後一場可加分的分數進行排序。找到要查詢的那個人,記錄下其分數以及當前排名。

最好名次:把可加的最好分數加給這個人那麼這個人分數是grade1,初始排名pm1設定為n,然後往後列舉的時候,如果加上b[i](排序之後是升序的,now從n-2開始)的分數仍然小於grade1或...那麼排名要上升的。如果迴圈完所有的b[i]都比grade1大即這個人的排名不能上升,直到now<0退出迴圈。

int grade1=grade+b[n-1];
int now=n-2;
for(int i=n-1;i>=0&&now>=0;i--)
{
	if(i!=pm)
	{
		while(now>=0)
		{
			if(a[i].score+b[now]<grade1 || (a[i].score+b[now]==grade1&&a[i].name>a[pm].name))break;
			now--;
		}
		now--;
		if(now<0)break;
		pm1--;
	}
}

最差名次同理。

【程式碼】

#include<bits/stdc++.h>
using namespace std;

const int maxn=1e5+10;
struct node{
	string name;
	int score;
}a[maxn];
int b[maxn]={0};

bool cmp(node x,node y)
{
	return x.score!=y.score?x.score>y.score:x.name<y.name;
}

int main()
{
	int n;scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		cin>>a[i].name;
		scanf("%d",&a[i].score);
	}
	int m;scanf("%d",&m);
	memset(b,0,sizeof(b));
	for(int i=0;i<m;i++)scanf("%d",&b[i]);
	string s;cin>>s;
	int grade,pm=0;
	sort(a,a+n,cmp);sort(b,b+n);
	for(int i=0;i<n;i++)
	{
		if(a[i].name==s)
		{
			grade=a[i].score;
			pm=i;
			break;
		}
	}
	int pm1=n,pm2=1;
	//good
	int grade1=grade+b[n-1];
	int now=n-2;
	for(int i=n-1;i>=0&&now>=0;i--)
	{
		if(i!=pm)
		{
			while(now>=0)
			{
				if(a[i].score+b[now]<grade1 || (a[i].score+b[now]==grade1&&a[i].name>a[pm].name))break;
				now--;
			}
			now--;
			if(now<0)break;
			pm1--;
		}
	}
	//bad
	int grade2=grade+b[0];
	now=1;
	for(int i=0;i<n&&now<n;i++)
	{
		if(i!=pm)
		{
			while(now<n)
			{
				if(a[i].score+b[now]>grade2 || (a[i].score+b[now]==grade2&&a[i].name<a[pm].name))break;
				now++;
			}
			if(now>=n)break;
			pm2++;
		}
	}
	printf("%d %d\n",pm1,pm2);
	return 0;
}