CCF 2018真題--持續更新ing
1 跳一跳
描述
近來,跳一跳這款小遊戲風靡全國,受到不少玩家的喜愛。
簡化後的跳一跳規則如下:玩家每次從當前方塊跳到下一個方塊,如果沒有跳到下一個方塊上則遊戲結束。
如果跳到了方塊上,但沒有跳到方塊的中心則獲得1分;跳到方塊中心時,若上一次的得分為1分或這是本局遊戲的第一次跳躍則此次得分為2分,否則此次得分比上一次得分多兩分(即連續跳到方塊中心時,總得分將+2,+4,+6,+8…)。
現在給出一個人跳一跳的全過程,請你求出他本局遊戲的得分(按照題目描述的規則)。
分析
模擬場景,還是很簡單那種。一個sum記錄總分,一個last記錄上一層得分,1的時候直接sum++;2的時候根據last來加分並修改last的值,0的時候輸出並return
參考程式碼
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
int n,sum=0,last=1;
while (cin>>n)
{
if (n == 1){sum++;last =1;}
else if(n==2)
{
if (last == 1){sum += 2;last = 2;}
else {
sum += (last + 2 );
last += 2;
}
}
else{
cout<<sum<<"\n";
return 0;
}
}
}
2 碰撞的小球
描述
數軸上有一條長度為L(L為偶數)的線段,左端點在原點,右端點在座標L處。有n個不計體積的小球線上段上,開始時所有的小球都處在偶數座標上,速度方向向右,速度大小為1單位長度每秒。
當小球到達線段的端點(左端點或右端點)的時候,會立即向相反的方向移動,速度大小仍然為原來大小。
當兩個小球撞到一起的時候,兩個小球會分別向與自己原來移動的方向相反的方向,以原來的速度大小繼續移動。
現在,告訴你線段的長度L,小球數量n,以及n個小球的初始位置,請你計算t秒之後,各個小球的位置。
因為所有小球的初始位置都為偶數,而且線段的長度為偶數,可以證明,不會有三個小球同時相撞,小球到達線段端點以及小球之間的碰撞時刻均為整數。
同時也可以證明兩個小球發生碰撞的位置一定是整數(但不一定是偶數)。
分析
也是模擬題,用了location陣列記錄每個小球的位置;v陣列記錄每個小球的速度;LL二維陣列(vector)記錄每個整數位置的小球的編號。在時間t下迴圈,每次遍歷一遍所有小球,根據v[i]修改其位置;遍歷完後遍歷位置,所有一個位置處小球數大於1的(只會有兩個),將這兩個編號小球的速度去相反數。看起來有點囉嗦
程式碼
#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
const int maxx = 200;
const int Lmax = 1005;
int locations[maxx];
vector<vector<int> >LL;
int v[maxx];
int main()
{
int n, L, t;
while (cin >> n >> L >> t)
{
LL.clear();
LL.resize(L + 1);
for (int i = 0; i < n; i++)
{
cin >> locations[i];
v[i] = 1;
}
while (t>0)
{
LL.clear();
LL.resize(L + 1);
for (int i = 0; i < n; i++)
{
if (locations[i] == L) {
v[i] = -v[i];
}
locations[i] += v[i];
LL[locations[i]].push_back(i);
}
for(int i =0;i<LL.size();i++)
if (LL[i].size() > 1)
{
v[LL[i][0]] = -v[LL[i][0]];
v[LL[i][1]] = -v[LL[i][1]];
}
t--;
}
for (int i = 0; i < n; i++)
printf("%d ", locations[i]);
}
return 0;
}
不知道為什麼,在vs2017上這個報vector下標越界,但是我提交之後就過了。。過了
上面那個方法有點囉嗦,習慣了直接無視O(n^2)級別的演算法,沒想到也能過。就是遍歷查詢此刻有沒有位置相同的,然後修改兩者的方向就好了!O(n^2)!過了!
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxx = 200;
const int Lmax = 1005;
int locations[maxx];
int v[maxx];
int main()
{
int n, L, t;
while (cin >> n >> L >> t)
{
for (int i = 0; i < n; i++)
{
cin >> locations[i];
v[i] = 1;
}
while (t>0)
{
//if (locations[0] == 0 && v[0] < 0)v[0] = -v[0];
//if (locations[0] == L)v[0] = -v[0];
//locations[0] = locations[0] + v[0];
for (int i = 0; i < n; i++)
{
if (locations[i] == L || (locations[i] == 0&&v[i]<0))v[i] = -v[i];
locations[i] = locations[i] + v[i];
for(int j =0;j<n;j++)
if (locations[i] == locations[j])
{
v[i] = -v[i];
v[j] = -v[j];
}
}
t--;
}
for (int i = 0; i < n; i++)
printf("%d ", locations[i]);
}
return 0;
}
3 URL對映
描述
問題描述
URL 對映是諸如 Django、Ruby on Rails 等網頁框架 (web frameworks) 的一個重要元件。對於從瀏覽器發來的 HTTP 請求,URL 對映模組會解析請求中的 URL 地址,並將其分派給相應的處理程式碼。現在,請你來實現一個簡單的 URL 對映功能。
本題中 URL 對映功能的配置由若干條 URL 對映規則組成。當一個請求到達時,URL 對映功能會將請求中的 URL 地址按照配置的先後順序逐一與這些規則進行匹配。當遇到第一條完全匹配的規則時,匹配成功,得到匹配的規則以及匹配的引數。若不能匹配任何一條規則,則匹配失敗。
本題輸入的 URL 地址是以斜槓 / 作為分隔符的路徑,保證以斜槓開頭。其他合法字元還包括大小寫英文字母、阿拉伯數字、減號 -、下劃線 _ 和小數點 .。例如,/person/123/ 是一個合法的 URL 地址,而 /person/123? 則不合法(存在不合法的字元問號 ?)。另外,英文字母區分大小寫,因此 /case/ 和 /CAse/ 是不同的 URL 地址。
對於 URL 對映規則,同樣是以斜槓開始。除了可以是正常的 URL 地址外,還可以包含引數,有以下 3 種:
字串 :用於匹配一段字串,注意字串裡不能包含斜槓。例如,abcde0123。
整數 :用於匹配一個不帶符號的整數,全部由阿拉伯數字組成。例如,01234。
路徑 :用於匹配一段字串,字串可以包含斜槓。例如,abcd/0123/。
以上 3 種引數都必須匹配非空的字串。簡便起見,題目規定規則中 和 前面一定是斜槓,後面要麼是斜槓,要麼是規則的結束(也就是該引數是規則的最後一部分)。而 的前面一定是斜槓,後面一定是規則的結束。無論是 URL 地址還是規則,都不會出現連續的斜槓。
輸入格式
輸入第一行是兩個正整數 n 和 m,分別表示 URL 對映的規則條數和待處理的 URL 地址個數,中間用一個空格字元分隔。
第 2 行至第 n+1 行按匹配的先後順序描述 URL 對映規則的配置資訊。第 i+1 行包含兩個字串 pi 和 ri,其中 pi 表示 URL 匹配的規則,ri 表示這條 URL 匹配的名字。兩個字串都非空,且不包含空格字元,兩者中間用一個空格字元分隔。
第 n+2 行至第 n+m+1 行描述待處理的 URL 地址。第 n+1+i 行包含一個字串 qi,表示待處理的 URL 地址,字串中不包含空格字元。
輸出格式
輸入共 m 行,第 i 行表示 qi 的匹配結果。如果匹配成功,設匹配了規則 pj ,則輸出對應的 rj。同時,如果規則中有引數,則在同一行內依次輸出匹配後的引數。注意整數引數輸出時要把前導零去掉。相鄰兩項之間用一個空格字元分隔。如果匹配失敗,則輸出 404。
樣例輸入
5 4
/articles/2003/ special_case_2003
/articles// year_archive
/articles/// month_archive
/articles//// article_detail
/static/ static_serve
/articles/2004/
/articles/1985/09/aloha/
/articles/hello/
/static/js/jquery.js
樣例輸出
year_archive 2004
article_detail 1985 9 aloha
404
static_serve js/jquery.js
樣例說明
對於第 1 個地址 /articles/2004/,無法匹配第 1 條規則,可以匹配第 2 條規則,引數為 2004。
對於第 2 個地址 /articles/1985/09/aloha/,只能匹配第 4 條規則,引數依次為 1985、9(已經去掉前導零)和 aloha。
對於第 3 個地址 /articles/hello/,無法匹配任何一條規則。
對於第 4 個地址 /static/js/jquery.js,可以匹配最後一條規則,引數為 js/jquery.js。
資料規模和約定
1 ≤ n ≤ 100,1 ≤ m ≤ 100。
所有輸入行的長度不超過 100 個字元(不包含換行符)。
保證輸入的規則都是合法的。
分析
這道題卡了很久..
算是一道大模擬的題,看上去不是很難,但是沒那麼容易過,最後的AC程式碼參考了 https://blog.csdn.net/nameofcsdn/article/details/79945925
m條URL每一個都要在n條規則中尋找一遍有沒有匹配的,還是把一條url與一條規則是否匹配單拿出來做函式的好
這位博主的程式碼用一個bool引數來確定這次是單純判斷是否符合還是輸出匹配的引數,反正我沒想到
判斷的時候用while迴圈比用for迴圈靈活許多,相等就continue;出現不等的情況,如果規則處不是’<’那肯定是不匹配了,return FALSE;
如果是’<’的話,就分三種情況:‘i’判斷數字,如果一直是數字就可以一直輸出,開始時判斷是否為0即可,如果不滿足這條規則就return false了,如果這個int匹配上了,就可以continue進行下一步了;
‘s’判斷str,輸出直到出現’/’為止;’p’判斷path,輸出直到最後。
最後如果沒有出現這些個引數的話,如果兩個一直匹配,那最後各自到達自己的長度時,就是完全匹配了
靈活使用continue return,讓程式碼變得很簡潔
程式碼
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cmath>
#include<cctype>
using namespace std;
string rules[101],names[101], qs[101];
bool ismatch(string q, string rule, bool flag)
{
int qlen = q.length(), rlen = rule.length();
int qi = 0, ri = 0;
while (qi<qlen && ri<rlen)
{
if (q[qi] == rule[ri])
{
qi++; ri++; continue;
}
if (rule[ri++] != '<')return false;
if (flag)cout << " ";
if (rule[ri] == 'i') {
bool flag2 = false;
while (qi < qlen && q[qi] >= '0' && q[qi] <= '9')
{
if (q[qi] > '0')flag2 = true;
if (flag && flag2)cout << q[qi];
qi++;
}
if (flag2 == false)return false;
ri += 4;
continue;
}
else if (rule[ri] == 's')
{
bool flag2 = false;
while (qi<qlen && q[qi]!='/' )
{
flag2 = true;
if (flag2 && flag)cout << q[qi];
qi++;
}
if (flag2 == false)return false;
ri += 4;
continue;
}
else if (rule[ri] == 'p')
{
while (qi<qlen)
{
if (flag)cout << q[qi];
qi++;
}
return true;
}
}
return (qi == qlen && ri == rlen);
}
int main()
{
int n, m;
while (cin>>n>>m)
{
for (int i = 0; i < n; i++)
{
cin >> rules[i]>>names[i];
}
string q;
for (int i = 0; i < m; i++) {
cin >> q;
bool fl = false;
for(int j=0;j<n;j++)
if (ismatch(q, rules[j], false))
{
fl = true;
cout << names[j] ;
ismatch(q, rules[j], true);
cout << "\n";
break;
}
if (fl == false)cout << "404\n";
}
}
}