第一題:報數(shù)
【題目】:
甲乙丙丁決定玩一個報數(shù)的游戲來打發(fā)時間。游戲規(guī)則為四個人從1開始輪流進行報數(shù),但如果需要報出的數(shù)是7的倍數(shù)或含有數(shù)字7則直接跳過。
此外大家約定,在總共報出了n個數(shù)后(不計入被跳過的數(shù))游戲結束?,F(xiàn)在需要你來幫忙統(tǒng)計,游戲過程中每個人各自跳過了幾次。
【輸入】:
從標準輸入讀入數(shù)據(jù)。
輸入僅一行,包含一個正整數(shù)n,表示報出了多少個數(shù)后游戲結束。
【輸出】:
輸出到標準輸出。
輸出共四行,每行一個整數(shù),依次表示甲乙丙丁四人在游戲過程中跳過的次數(shù)。
思路:水題沒什么好說的,代碼如下
#include<iostream>
using namespace std;
int main()
{
int n;
int gamer[10];
int number;
int count;
while (cin >> n)
{
count=gamer[1] = gamer[2] = gamer[3] = gamer[0]=0;
for (int i = 1; count!=n; i++)
{
if (i % 7 == 0)
{
gamer[i % 4]++;
continue;
}
else
{
number = i;
while (number)
{
if (number % 10 == 7)
{
gamer[i % 4]++;
count--;
break;
}
else number = number / 10;
}
}
count++;
}
//4取余是0,故丁的位置在gamer[0]而不是gamer[4]
cout << gamer[1] << endl << gamer[2] << endl << gamer[3] << endl << gamer[0] << endl;
}
}
第二題: 回收站選址
【題目】:
開學了,可是校園里堆積了不少垃圾雜物。
熱心的同學們紛紛自發(fā)前來清理,為學校注入正能量~
通過無人機航拍我們已經知曉了n處尚待清理的垃圾位置,其中第i(1<=i<=n)處的坐標為(x,y),保證所有的坐標均為整數(shù)。
我們希望在垃圾集中的地方建立些回收站。具體來說,對于一個位置(x, y)是否適合建立回收站,我們主要考慮以下幾點:
(x, y)必須是整數(shù)坐標,且該處存在垃圾:上下左右四個鄰居位置,即(x, y+1),(x, y-1),(x+1, y)和(x-1, y)處,必須全部存在垃圾:進一步地,我們會對滿足上述兩個條件的選址進行評分,分數(shù)為不大于4的自然數(shù),表示在(x±1,y±1)四個對角位置中有幾處存在垃圾。
現(xiàn)在,請你統(tǒng)計一下每種得分的選址個數(shù)。
【輸入】:
從標準輸入讀入數(shù)據(jù)。輸入總共有n+1行。
第1行包含一個正整數(shù)n,表示已查明的垃圾點個數(shù)。
第1+i行(1<=i<=n)包含由一個空格分隔的兩個整數(shù)xi和yi,表示第i處垃圾的坐標。
保證輸入的n個坐標互不相同。
【輸出】:
輸出到標準輸出。
輸出共五行,每行一個整數(shù),依次表示得分為0、1、2、3和4的回收站選址個數(shù)。
思路:
1.一般做題要么是用空間換時間要么是時間換空間,如果本體使用二維數(shù)組模擬坐標,測試用例是有用10000以上的坐標作為測試數(shù)據(jù)的,如果使用二維數(shù)組模擬坐標就說明最起碼得有index[10000][10000],這顯然不現(xiàn)實。
2.所以只能用時間換空間,大力出奇跡就完事了。直接用兩重循環(huán),依次比較一個點上下左右的坐標值在數(shù)組中有無對應,如果有再判斷對角線上的。時間復雜度為:o(n^2)。
代碼如下:
#pragma warning(disable:4996)
#include<iostream>
using namespace std;
int main()
{
int n;
int dp;
int input[500];
int member[20];
int i,j;
int flag;
while (cin >> n)
{
memset(member, 0, sizeof(member));
for (i = 0; i < 2 * n; i = i + 2)
cin >> input[i] >> input[i + 1];
for (i = 0, flag = 0, dp = 0; i < 2 * n; i = i + 2,flag=0,dp=0)
{
for (j = 0;j < 2 * n; j = j + 2)
{
if ((input[i] + 1 == input[j] && input[i + 1] == input[j + 1]) ||
(input[i] == input[j] && input[i + 1] + 1 == input[j + 1]) ||
(input[i] - 1 == input[j] && input[i + 1] == input[j + 1]) ||
(input[i] == input[j] && input[i + 1] - 1 == input[j + 1])
)flag++;
}
if (flag == 4)
{
for (j = 0; j < 2 * n; j = j + 2)
{
if ((input[i] + 1 == input[j] && input[i + 1] + 1 == input[j + 1]) ||
(input[i] + 1 == input[j] && input[i + 1] - 1 == input[j + 1]) ||
(input[i] - 1 == input[j] && input[i + 1] + 1 == input[j + 1]) ||
(input[i] - 1 == input[j] && input[i + 1] - 1 == input[j + 1])
)dp++;
}
member[dp]++;
}
}
cout << member[0] << endl << member[1] << endl << member[2] << endl << member[3] << endl << member[4] << endl;
}
}
第三題:化學方程式(沒做出)
【題目】:
化學方程式,也稱為化學反應方程式,是用化學式表示化學反應的式子。給出一組化學方程式,請你編寫程序判斷每個方程式是否配平(也就是方程式中等號左右兩邊的元素種類和對應的原子個數(shù)是否相同)。
本題給出的化學方程式由大小寫字母、數(shù)字和符號(包括等號=、加號+、左圓括號和右圓括號)組成,不會出現(xiàn)其他字符(包括空白字符,如空格、制表符等),化學方程式的格式與化學課本中的形式基本相同(化學式中表示元素原子個數(shù)的下標用正常文本,如H2O寫成H2O),用自然語言描述如下:
化學方程式由左右兩個表達式組成,中間用一個等號三連接,如2H2+O2=2H2O;
表達式由若干部分組成,每部分由系數(shù)和化學式構成,部分之間用加號+連接,如2H2+O2、2H2O;
系數(shù)是整數(shù)或空串,如為空串表示系數(shù)為1;
整數(shù)由一個或多個數(shù)字構成;
化學式由若干部分組成,每部分由項和系數(shù)構成,部分之間直接連接,如H2O、CO2、Ca(OH)2、Ba3(PO4)2;
項是元素或用左右圓括號括起來的化學式,如H、Ca、(OH)、(P04);
元素可以是一個大寫字母,也可以是一個大寫字母跟著一個小寫字母,如H、O、Ca。
【輸入】:
從標準輸入讀入數(shù)據(jù)。
輸入的第一行包含一個正整數(shù)n,表示輸入的化學方程式個數(shù)。
接下來n行,每行是一個符合定義的化學方程式。
【輸出】:
輸出到標準輸出。
輸出共n行,每行是一個大寫字母Y或N,回答輸入中相應的化學方程式是否配平。
思路:
1、一個元素必然由一個大寫字母開頭如C,Cl,所以將大寫字母開頭的視為一個元素,如果開頭的是數(shù)字,那么后面全體元素個數(shù)都要乘以這個數(shù)字,如果數(shù)字在元素后面出現(xiàn),那么這個數(shù)字的前一個元素就要乘以這個數(shù)字。
做不出來的地方:括號嵌套。有些案例嵌套非常多的括號,如果要解決這個問題要加入很多判斷,我又想不到特別精簡的做法。最近忙著學習安卓開發(fā),無瑕再畫大量時間去剛一道碼量巨多的題。
#pragma warning(disable:4996)
#include<iostream>
#include<sstream>
#include <string>
#include <vector>
#include<algorithm>
#include<map>
#include<ctype.h>
#include <math.h>
using namespace std;
bool judge(map<char, int> &left, map<char, int> &right) { //判斷兩個map是否相同
if (left.size() != right.size()) return false;
for (map<char, int>::iterator it = left.begin(); it != left.end(); ++it) {
if (right[it->first] != it->second) return false;
}
return true;
}
int get_string_int(string s, int pos)
{
int number;
int j;
stringstream stream;
string num;
for (j = pos + 1; j < s.length(); j++)
if (!isdigit(s[j]))
break;
num = s.substr(pos, j);//substr不包括j
stream<<num;
stream >> number;
return number;
}
map<char, int> count_alphabet(string equation_part[50])
{
int i,j,k,now_index,base,end_base;
map<char, int> hash;
for (i = 0; i < equation_part->length(); i++)
{
if (isdigit(equation_part[i][0]))//如果某個開頭是數(shù)字,就要確認他的base
{
base = get_string_int(equation_part[i], 0);
for (j = log10(base) + 1, now_index= log10(base); j < equation_part[i].length(); j++)//計算字符
{
if (isdigit(equation_part[i][j]))
{
//cout << "left_equation_part[i][j])=" << left_equation_part[i][j]<< endl;
end_base = get_string_int(equation_part[i], j);//這一行出異常
//cout << "base=" << base << " " << "end_base=" << end_base << endl;
for (k = now_index; k < j; k++)//回到第一個字符出現(xiàn)的位置
{
hash[equation_part[i][k]] += 1 * base*end_base;
}
//更新下一個字符起始位置,循環(huán)結束會++
j = now_index = j + log10(end_base);
}
else if (j == equation_part[i].length()-1)
{
end_base = 1;//這一行出異常
//cout << "base=" << base << " " << "end_base=" << end_base << endl;
for (k = now_index+1; k <= j; k++)//回到第一個字符出現(xiàn)的位置
{
hash[equation_part[i][k]] += 1 * base*end_base;
}
//更新下一個字符起始位置,循環(huán)結束會++,所以在此減1
j = now_index = j + log10(end_base);
}
}
}
else
{
base = 1;
for (j = now_index = 0; j < equation_part[i].length(); j++)//計算字符
{
if (isdigit(equation_part[i][j]))
{
end_base = get_string_int(equation_part[i], j);//這一行出異常
for (k = now_index; k < j; k++)//回到第一個字符出現(xiàn)的位置
{
hash[equation_part[i][k]] += 1 * base*end_base;
}
j = now_index = j + log10(end_base);
}
else if (j == equation_part[i].length() - 1)
{
end_base = 1;//這一行出異常
//cout << "base=" << base << " " << "end_base=" << end_base << endl;
for (k = now_index + 1; k <= j; k++)//回到第一個字符出現(xiàn)的位置
{
hash[equation_part[i][k]] += 1 * base*end_base;
}
//更新下一個字符起始位置,循環(huán)結束會++,所以在此減1
j = now_index = j + log10(end_base);
}
}
}
}
return hash;
}
int main()
{
map<char, int> left_map;
map<char, int> right_map;
int n,m;
int i, j, k;
int base,end_base;
int index,pos,now_index;
string total_equation;
string left_equation;
string right_equation;
string left_equation_part[50];
string right_equation_part[50];
cin >> n;
while (n)
{
pos=m=index = 0;
cin >> total_equation;
left_equation = total_equation.substr(0, total_equation.find("="));
right_equation = total_equation.substr(total_equation.find("=")+1,total_equation.length());
//切割等號左邊
while (left_equation.find("+",pos)!=string::npos)
{
index = left_equation.find("+",pos);
left_equation_part[m++] = left_equation.substr(pos,index);
pos = index+1;
}
left_equation_part[m++] = left_equation.substr(pos, left_equation.length());
//切割等號右邊
pos = m = index = 0;
while (right_equation.find("+", pos) != string::npos)
{
index = right_equation.find("+", pos);
right_equation_part[m++] = right_equation.substr(pos, index);
pos = index + 1;
}
right_equation_part[m++] = right_equation.substr(pos, right_equation.length());
cout << left_equation << endl<<"?"<< right_equation_part[0] <<endl;
//下面開始處理左邊的
//cout << "下面開始處理左邊的" << endl;
left_map=count_alphabet(left_equation_part);
//下面開始處理右邊的
//cout << "下面開始處理右邊的" << endl;
right_map=count_alphabet(right_equation_part);
if (judge(left_map, right_map)) cout << "Y" << endl;
else cout << "N" << endl;
}
}