【紀中2020.5.16日】模擬賽題解

目錄:

T1:mobitel
T2:airship
T3:reuntion
T4:house

USACO,永遠滴神!

正題

T1:mobitel

題目描述

一隻名叫馬可的蚱蜢在草地上高興地蹦躂。一不小心, 他的諾基亞3310掉進了水坑裏。現在,他的手機變得很滑稽。鍵盤溼了,而且完全按照不可預測的方式按出不符的字符。所有的數字鍵都崩潰了。當我們按下其中某一個按鈕時,就如同我們在按另一個鍵一樣。幸運的是,沒有兩個鍵是相同的。所以,馬可仍然可以拼寫所有的字母。

馬可正在一個一個地嘗試,看看每個按鍵能按出什麼字符。現在他想給他的女朋友發短信,可是,他被這個錯亂的按鍵弄糊塗了,所以請你幫忙發短信。對於手機原來的按鍵,這裏有一個簡短的描述。

這是一個諾基亞手機的按鍵面板。該圖像顯示按鍵上(在沒有落入水坑時的手機)可以獲得的字母的鍵。例如,如果我們要獲取字母‘a’,我們將按“2鍵”一次,如果我們想要字母‘b’,我們將按“2鍵”兩次。如果我們想從同一個鍵連續寫兩個不同的字母,我們必須按‘#’間隔。例如,我們要寫字符串“klor”,我們將要按鍵的順序如下:“55#555666777”。

輸入

第 1 行輸入包含9個數字。
第一個整數表示 “鍵1”實際按出的數字,第二個整數表示“鍵2”實際按出的數字,第三個整數表示“鍵3”實際按出的數字,以此類推(且保證數字1~9,每個數字當且僅當出現一次)。因爲他是一隻蚱蜢,所以馬可沒有使用“*”和“0”鍵。“#”鍵沒有壞掉。
第 2 行輸入一個字符串S,由英文小寫字母組成。

輸出

輸出共一行一個字符串,即輸出馬可的信息,你需要按鍵的數字序列。

樣例輸入

【輸入樣例1】

2 3 4 5 6 7 8 9 1
klor

【輸入樣例2】

7 8 9 1 2 3 6 5 4
djevojka

【輸入樣例3】

9 8 7 6 5 4 3 2 1
skakavac

樣例輸出

【輸出樣例1】

44#444555666

【輸出樣例2】

68662227778#885

【輸出樣例3】

33335585582228#888

分析:

一道 簡易的 字符串模擬

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring> 
using namespace std;
int a[10];
string s;
int before_num;
int c[27]={0,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,7,7,7,8,8,8,9,9,9,9};
 //鍵位
int sum[27]={0,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};
//需要按的次數
void init_(){  //讀入
	for(int i=1;i<=9;i++){
		int x;cin>>x;
		a[x]=i;
	}
	cin>>s;
}
int main(){
	freopen("mobitel.in","r",stdin);
	freopen("mobitel.out","w",stdout);
	init_(); 
	for(int i=0;i<s.size();i++){  //掃描
		int num=s[i]-'a'+1;
		if(before_num==c[num]) cout<<'#';  //根據題意
		before_num=c[num];  //往後更新
		for(int j=1;j<=sum[num];j++)
		    cout<<a[c[num]];
	}
	return 0;
}

T2:airship

題目描述

2008年9月25日21點10分,酒泉衛星發射中心指控大廳裏,隨着指揮員一聲令下,長征二號F型火箭在夜空下點火起飛,神舟七號飛船載着翟志剛、劉伯明、景海鵬3位航天員,在戈壁茫茫的深邃夜空中飛向太空,開始人類漫步太空之旅。第583秒,火箭以7.5公里/秒的速度,將飛船送到近地點200公里、遠地點350公里的橢圓軌道入口。
而此時,火箭的燃料也消耗殆盡,即將以悲壯的方式與飛船告別。這個過程,在短短不到10分鐘時間內,翟志剛和他的兩名戰友體會到了從超重到失重的過程。 除了超重和失重的感覺之外,就是浩瀚的長空中璀璨的星星,和地面上看到的星星不同,在太空中看到的星星是成一條直線的,一共N(1<=N<=100,000)顆星星,編號爲1到N,每個星星有自己的體積。
由於在飛船中很無聊,除了不停地玩弄手中失重的書和筆之外沒有別的事可幹,此時翟志剛說我們來玩遊戲吧,一共玩了M輪(1<=M<=100,000),每一輪都是給出兩個整數L和R(1<=L<=R<=N),詢問第L到第R顆星星之間最大星星的體積,每次答對的人就可以多休息一段時間。由於翟志剛還要進行太空漫步,所以他現在請你幫忙,你得到的回報就是太空餅乾。

輸入

第一行輸入N,M 接下來一行N個整數,表示星星的體積(1<=體積<=maxlongint) 接下來M行,每行兩個整數L_i,R_i,表示詢問區間。

輸出

輸出M行,每一行表示詢問區間L_i到R_i之間最大星星的體積。

樣例輸入

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

樣例輸出

7
9
10

分析:

存星星的位置 星星體積從小到大排序 然後判斷
符合區間就輸出

CODE:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<map>
using namespace std;
int n,m,l,r,maxn;
struct c {
	int x,y;
}a[100010];
bool cmp(const c&l,const c&r)
{
	return l.x>r.x;  //體積排序
}
int main() {
	freopen("airship.in","r",stdin);
	freopen("airship.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1; i<=n; i++) {
		scanf("%d",&a[i].x);
		a[i].y=i;  //存位置
	}
	sort(a+1,a+n+1,cmp);  //排序
	for(int i=1; i<=m; i++) {
		scanf("%d%d",&l,&r);
		for(int j=1; j<=n; j++) {
			if(a[j].y>=l&&a[j].y<=r) {  //符合區間
				printf("%d\n",a[j].x);  //輸出
				break;
			}
		}
	}
	return 0;
}

T3:reuntion

題目描述

畢業20年以後,我們的主人公開始準備同學聚會。打了無數電話後他終於搞到了所有同學的地址。他們有些人仍在本市,但大多數人分散在其他的城市。不過,他發現一個巧合,所有地址都恰好分散在一條鐵路線上。他準備發出邀請但無法決定應該在哪個地方舉行宴會。最後他決定選擇一個地點,使大家旅行的總花費最小。我們的主人公既不擅長數學,也不擅長計算機。他請你這個NOIP的高手幫忙寫一個程序,根據他同學的地址,選擇聚會的最佳地點。

輸入

輸入文件的每一行描述了一個城市的信息。(不超過10000個城市),首先是城裏同學的個數(保證總人數在2^32範圍內),緊跟着是這個城市到Moscow(起始點)的距離(km),最後是城市的名稱。最後一行描述的總是Moscow,它在鐵路線的一端,距離爲0,三個數據之間分別用空格隔開。

輸出

輸出聚會地點城市名稱和旅程費用(單程),兩者之間用一個空格隔開。每km花費1元人民幣。總距離保證在2^64範圍內。

樣例輸入

7 9289 Vladivostok
5 8523 chabarovsk
3 5184 Irkutsk
8 2213 Yalutorovsk
10 0 Moscow

樣例輸出

Yalutorovsk 112125

分析:

so……
直接求出每個地點的花費 然後根據花費排序 輸出第一位
(也就是最小的一位 自己想)

CODE:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct node{
	int distancE;  //距離
	int stu;  //人數
	string name;  //名字
	int pay;  //花費
}a[90001];
int n=0;
bool cmp(node x,node y)
{
	if(y.pay==x.pay)  //花費一致按距離
	{
		return x.distancE<y.distancE;
	}
	return x.pay<y.pay;  
}
int main()
{
	freopen("reuntion.in","r",stdin);
	freopen("reuntion.out","w",stdout);
	while(true)
	{
		++n;
		cin>>a[n].stu>>a[n].distancE>>a[n].name;
		if(a[n].name=="Moscow") break;  //輸入
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			a[i].pay+=abs(a[j].distancE-a[i].distancE)*a[j].stu;  //算出花費
		}
	}
	sort(a+1,a+n+1,cmp);  //排序
	cout<<a[1].name<<" "<<a[1].pay;  //最小的
	return 0;
}

T4:house

題目描述

奶牛們想建立一個新的城市。它們想建立一條長度爲 Len 的主線大街,然後建立 K 條小街,每條小街的盡頭有一間房子(小街的其它位置沒有房子)。每條小街在主線大街的P_i 處分支, 小街的長度用L_i表示。FJ想知道最遠的兩個房子之間的距離是多少。

輸入

第 1 行: 兩個整數 Len 和K,意義如題目描述。
第2…K+1行: 每行兩個整數P_i和L_i,對應着一條小街的信息。

輸出

輸出共一行一個整數,即最遠的兩個房子之間的距離。

樣例輸入

【輸入樣例1】

5 4
5 6
2 2
0 3
2 7

【輸入樣例2】

5 4
2 4
2 2
2 10
2 7

樣例輸出

【輸出樣例1】

16

【輸出樣例2】

17

分析:

一句話:排序,永遠滴神!
普通的思路:
ans(i,j)=l[i]+l[j]+abs(p[i]-p[j])
做一遍從小到大的排序
即可去掉絕對值
ans(i,j)=l[i]+l[j]+p[i]-p[j]
然後合併一下:
ans(i,j)=l[i]+p[i]+(l[j]-p[j])
最後的答案就等於max(ans(i,j))
要使答案最大 那麼ans(i,j)就要儘可能大
可以解決一些多餘的運算 不然本來60分

CODE:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int max1,max2,len,n;
struct node
{
	int Bifurcations,l;
} a[500010];
void input()
{
	scanf("%d%d",&len,&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&a[i].Bifurcations,&a[i].l);  //分叉與距離
}
bool cmp(node x,node y){
	return x.Bifurcations<y.Bifurcations;
}
int main()
{
	freopen("house.in","r",stdin);
	freopen("house.out","w",stdout);
	input();
	sort(a+1,a+1+n,cmp);  //排序,永遠滴神!
	max2=a[1].l-a[1].Bifurcations;
	for(int i=1;i<=n;i++)
	{
		max1=max(max2+a[i].Bifurcations+a[i].l,max1);  //最終的答案
		max2=max(max2,a[i].l-a[i].Bifurcations);
	}
	printf("%d",max1);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章