目錄:
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;
}