第一题 Let the Balloon Rise
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1001&cid=34727
用结构体或者map来统计某一颜色出现的最多次数
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main(){
int n;
while (cin >> n&&n)
{
string s, b[1010], ans;
int num, max = 0;
map <string, int>mp;
for (int i = 0; i < n; i++)
cin >> s, mp[s]++, b[i] = s; //统计单词出现次数
for (int i = 0; i < n; i++)
if (mp[b[i]] > max)
max = mp[b[i]], ans = b[i];
cout << ans << endl;
}
return 0;
}
第二题 手机短号
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1002&cid=34727
用substr返回该手机号的后五位,输出6+该字串即可
#include<iostream>
#include<string>
using namespace std;
int main(){
int n;
cin >> n;
while (n--)
{
string a;
cin >> a;
cout << "6" << a.substr(6) << endl;
}
return 0;
}
第三题Online Judge
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1003&cid=34727
将二次输入的数据中空格,换行,制表都去掉,再进行对比
来判断AC,PE,WA。如果原字符串相同则AC,若去掉空格,换行,制表后相同即PE,否则WA
#include<iostream>
#include<string>
#include<stdio.h>
using namespace std;
int main(){
int t;
cin >> t;
getchar();
while (t--)
{
string s, a[2], b[2]; //用a来表示原字符串,b来表示转化后的字符串
for (int i = 0; i < 2; i++){
getline(cin, s);
while (1){
getline(cin, s);
if (s != "END")
a[i] += s + '\n';
else break;
}
int len = a[i].size();
for (int j = 0; j < len; j++)
if (a[i][j] != '\t'&&a[i][j] != '\n'&&a[i][j] != ' ') //将空格,制表,换行去掉,其余字符加入b中
b[i] += a[i][j];
}
if (b[0] != b[1]) // 如果去掉空格制表换行后, 仍然不同即答案错误
cout << "Wrong Answer" << endl;
else
if (a[0] != a[1]) // 若去掉空格制表换行后, 但加上又不同即是格式错误
cout << "Presentation Error" << endl;
else
cout << "Accepted" << endl; // 都不满足即答案错误
}
return 0;
}
第四题 亲和串
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?cid=34727&pid=1004
将S1增加为原来的两份,再判断S2是否为其增加后的子串
#include<iostream>
#include<string>
using namespace std;
int main(){
string a, b;
while (cin >> a >> b) // 将原串扩征两倍后, 即原串任意移动后的情况均可在新串中出现
{
if (a.size() < b.size())
cout << "no" << endl;
else
{
a = a + a;
if (a.find(b) != -1)
cout << "yes" << endl;
else
cout << "no" << endl;
}
}
return 0;
}
第五题 Easier Done Than Said?
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1005&cid=34727
题目的意思就是输入一串密码,判断是否满足题目要求
要求即为必须含有一个元音字母,且不能有超过三个以及以上的连续元音字母和辅音字母
除了o和e外,其余字母不能有重复
#include<iostream>
#include<string>
using namespace std;
int vowel(char a){
if (a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u')
return 1;
return 0;
}
int main(){
string a;
while (cin >> a&&a != "end")
{
int flag1 = 0, flag2 = 1, count2 = 0, count1 = 0;
int len = a.size();
for (int i = 0; i < len; i++){
if (vowel(a[i]) == 1)
flag1 = 1;
if (vowel(a[i]) == 1)
count2 = 0, count1++;
else
count2++, count1 = 0;
if (count1 >= 3 || count2 >= 3)
flag2 = 0;
}
for (int i = 1; i < len; i++)
if (a[i] == a[i - 1] && a[i] != 'e'&&a[i] != 'o')
flag2 = 0;
if (flag1&&flag2)
cout << '<' << a << '>' << " is acceptable." << endl;
else
cout << '<' << a << '>' << " is not acceptable." << endl;
}
return 0;
}
第六题 壮志难酬
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1006&cid=34727
题意如题目
用find找出小数点出现的下标,再加上k即是所求,如果超出范围,输出0
#include<iostream>
using namespace std;
int main(){
int t;
cin >> t;
while (t--)
{
string a;
int k;
cin >> a;
cin >> k;
if (a.size() - 1 - a.find('.') < k)
cout << "0" << endl;
else
cout << a[a.find('.') + k] << endl;
}
return 0;
}
第七题 终曲
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1007&cid=34727
枚举的方法,把原串的子串枚举出来,把满足条件的子串存入set。
第一个长度为最短的即是要求条件的。
#include<iostream>
#include<algorithm>
#include<set>
#include<string>
using namespace std;
int main(){
int t;
cin >> t;
string a, b, c;
while (t--){
string M;
set<string>s;
int min1 = 10000;
cin >> a >> b >> c;
if (a.find(b) == -1 || a.find(c) == -1)
cout << "No" << endl;
else
{
for (int i = 0; i < a.size(); i++)
for (int z = a.size() - i; z >= 1; z--)
{
int k = z;
string f = a.substr(i, z);
if (f.find(b) != -1 && f.find(c) != -1)
s.insert(f), min1 = min(min1, z);
}
for (auto &i:s)
if (i.size() == min1)
{
cout << i << endl;
break;
}
}
}
return 0;
}
第八题Substrings
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1008&cid=34727
跟第七题一样用枚举的方法,枚举的对象是最短字符串的子串,记录最长的子串长度
再更: 这题少加个等号..杭电数据水了。 这题可以用后缀数组来做, 将正串反串拼接, 并记录位置。
当然这题数据比较弱。暴力更好写。
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int main(){
int t;
cin >> t;
while (t--)
{
int n;
string a[110], b, c, d;
cin >> n;
cin >> a[0];
b = a[0];
for (int i = 1; i < n; i++)
{
cin >> a[i];
if (a[i].size() < b.size())
b = a[i]; //记录长度最短的字符串
}
int max = 0;
for (int i = 0; i < b.size() - 1; i++)
for (int z = b.size() - i; z >= 1; z--)
{
int sum = 0, k = z;
d = c = b.substr(i, z);
reverse(d.begin(), d.end());
for (int j = 0; j < n; j++)
{
if (a[j].find(c) != -1 || a[j].find(d) != -1)
sum++;
}
if (sum == n)
{ //该子串需要满足为所有串的子串
if (k > max)
max = k;
}
}
cout << max << endl;
}
return 0;
}
后缀数组:
//#include <bits/stdc++.h>
#include <time.h>
#include <string>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <functional>
#include <set>
//#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#ifdef LOCAL
#define debug(x) cout << "[" __FUNCTION__ ": " #x " = " << (x) << "]\n"
#define TIME cout << "RuningTime: " << clock() << "ms\n", 0
#else
#define TIME 0
#endif
#define hash_ 1000000009
#define Continue(x) { x; continue; }
#define Break(x) { x; break; }
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define gc p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
inline int read(){ static char buf[1000000], *p1 = buf, *p2 = buf; register int x = false; register char ch = gc; register bool sgn = false; while (ch != '-' && (ch < '0' || ch > '9')) ch = gc; if (ch == '-') sgn = true, ch = gc; while (ch >= '0'&& ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc; return sgn ? -x : x; }
ll fpow(ll a, int b, int mod) { ll res = 1; for (; b > 0; b >>= 1) { if (b & 1) res = res * a % mod; a = a * a % mod; } return res; }
int str[N];
int record[N];
char s[N];
int vis[410];
int idx;
int cnt;
int n;
struct SA
{
int n, r;
int cnt[N];
int sa[N];
int tmp[N];
int rak[N];
int heig[N];
void radix_sort(int* rk, int* tp)
{
memset(cnt, 0, sizeof cnt);
for (int i = 1; i <= n; i++)
cnt[rk[tp[i]]]++;
for (int i = 1; i <= r; i++)
cnt[i] += cnt[i - 1];
for (int i = n; i >= 1; i--)
sa[cnt[rk[tp[i]]]--] = tp[i];
}
void suffix()
{
int *rk = rak, *tp = tmp;
for (int i = 1; i <= n; i++)
rk[i] = str[i], tp[i] = i;
r = 400;
radix_sort(rk, tp);
for (int l = 1, p = 0, i; p < n; l <<= 1, r = p)
{
p = 0;
for (i = n - l + 1; i <= n; i++)
tp[++p] = i;
for (i = 1; i <= n; i++)
if (sa[i] > l)
++p, tp[p] = sa[i] - l;
radix_sort(rk, tp);
swap(rk, tp);
rk[sa[1]] = 1;
p = 1;
for (i = 2; i <= n; i++)
{
if (tp[sa[i]] != tp[sa[i - 1]] || tp[sa[i] + l] != tp[sa[i - 1] + l])
p++;
rk[sa[i]] = p;
}
}
}
void get_heig()
{
for (int i = 1; i <= n; i++)
rak[sa[i]] = i;
int k = 0;
for (int i = 1; i <= n; i++)
{
if (k)
k--;
int j = sa[rak[i] - 1];
while (str[i + k] == str[j + k])
k++;
heig[rak[i]] = k;
}
}
}sa;
int id(int m)
{
if (m % 2 == 0 && m)
return m - 1;
else
if (m)
return m + 1;
}
bool check(int mid)
{
int cnt = 0;
memset(vis, 0, sizeof vis);
vis[0] = 1;
if (!vis[record[sa.sa[1]]] && !vis[id(record[sa.sa[1]])])
{
cnt++;
vis[record[sa.sa[1]]] = 1;
vis[id(record[sa.sa[1]])] = 1;
}
int flag = 1;
for (int i = 2; i <= sa.n; i++)
{
if (sa.heig[i] >= mid)
{
flag = 1;
if (!vis[record[sa.sa[i]]] && !vis[id(record[sa.sa[i]])])
{
cnt++;
vis[record[sa.sa[i]]] = 1;
vis[id(record[sa.sa[i]])] = 1;
}
}
else
{
cnt = 0;
memset(vis, 0, sizeof vis);
vis[0] = 1;
if (!vis[record[sa.sa[i]]] && !vis[id(record[sa.sa[i]])])
{
vis[record[sa.sa[i]]] = 1;
vis[id(record[sa.sa[i]])] = 1;
cnt++;
}
flag = 0;
}
if (cnt == n && flag)
return true;
}
return false;
}
void solve()
{
int L = 0, R = idx, ans = 0;
while (L <= R)
{
int mid = L + R >> 1;
if (check(mid))
L = mid + 1, ans = mid;
else
R = mid - 1;
}
cout << ans << endl;
}
int main()
{
#ifdef LOCAL
freopen("D:/input.txt", "r", stdin);
#endif
int t;
cin >> t;
while (t--)
{
memset(record, 0, sizeof record);
idx = 0;
int u = 0, le = 1;
cin >> n;
for (int i = 1; i <= n; i++)
{
scanf("%s", s + 1);
int len = strlen(s + 1);
for (int j = 1; j <= len; j++)
{
str[++idx] = s[j] + 200;
record[idx] = le;
}
++le;
str[++idx] = ++u;
for (int j = len; j >= 1; j--)
{
str[++idx] = s[j] + 200;
record[idx] = le;
}
++le;
str[++idx] = ++u;
}
sa.n = idx;
sa.suffix();
sa.get_heig();
solve();
}
return TIME;
}
第九题排序
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1009&cid=34727
题意如题目,用stringstream和string都可以做,这里写两种做法
string的做法
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int getnum(string a){
int sum = 0;
for (int i = 0; i < a.size(); i++)
sum = sum * 10 + a[i] - '0';
return sum;
}
int main(){
string a;
while (cin >> a)
{
int x = 0, k = 0, i = 0;
int s[1010];
if (a[0] == '5')
{
while (a[i] == '5')i++; //将最前面的5抵消掉
}
k = i; //默认起始下标为第一个非5的字符
if (a[a.size() - 1] != '5')s[x++] = getnum(a.substr(a.find_last_of('5') + 1));
for (i = i + 1; i < a.size(); i++)
{
int flag = 0;
if (a[i] == '5')s[x++] = getnum(a.substr(k, i - k)), flag = 1;//取被截取的子串存入数组
while (a[i] == '5')i++;
if (flag == 1)k = i; //更新起始的下标
}
sort(s, s + x); //将存入数组的数排序
for (int i = 0; i < x; i++)
{
cout << s[i];
if (i != x - 1)cout << " ";
}
cout << endl;
}
return 0;
}
stringstream的做法
#include<iostream>
#include<string>
#include<sstream>
#include<algorithm>
#include<string.h>
using namespace std;
int ans[1010];
int main(){
string s;
while (cin >> s)
{
memset(ans, 0, sizeof(ans));
int len = s.size();
for (int i = 0; i < len; i++)
if (s[i] == '5')s[i] = ' '; // 将5变成空格, 用于下面的分割
stringstream ss;
ss << s;
int x = 0;
for (;;)
{
int b;
ss >> b;
if (ss.fail())
break;
ans[x++] = b;
}
sort(ans, ans + x);
for (int i = 0; i < x; i++)
{
if (i == 0)
cout << ans[0];
else
cout << " " << ans[i];
}
cout << endl;
}
return 0;
}
第十题:Telephone Numbers
链接http://acm.hdu.edu.cn/diy/contest_showproblem.php?pid=1010&cid=34727
时隔几个月, 再做这题, 还是没过呜呜
下面是最近写的代码。
嘤嘤嘤
#include <iostream>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
using namespace std;
char r(char a){
if (a == 'Q' || a == 'Z')return '1';
if (a == 'A' || a == 'B' || a == 'C')return '2';
if (a == 'D' || a == 'E' || a == 'F')return '3';
if (a == 'G' || a == 'H' || a == 'I')return '4';
if (a == 'J' || a == 'K' || a == 'L')return '5';
if (a == 'M' || a == 'N' || a == 'O')return '6';
if (a == 'P' || a == 'R' || a == 'S')return '7';
if (a == 'T' || a == 'U' || a == 'V')return '8';
if (a == 'W' || a == 'X' || a == 'Y')return '9';
}
string a[20010];
string b[20010];
string c[20010];
bool cmp(string a, string b)
{
if (a.size() != b.size())
return a.size() > b.size();
else
return a < b;
}
map<string, vector<int>>mp;
int main(){
int cnt1 = 0, cnt2 = 0;
string s;
while (cin >> s)
{
if (s == "#")
break;
if (s[0] <= '9' && s[0] >= '0')
{
s.erase(3, 1);
b[cnt2++] = s;
}
else
a[cnt1++] = s;
}
sort(a, a + cnt1, cmp);
for (int i = 0; i < cnt1; i++)
{
int len = a[i].size();
for (int j = 0; j < len; j++)
c[i].push_back(r(a[i][j]));
mp[c[i]].push_back(i);
}
for (int i = 0; i < cnt2; i++, cout << endl)
{
for (int w = 0; w < 3; w++)
cout << b[i][w];
cout << "-";
for (int w = 3; w < 7; w++)
cout << b[i][w];
cout << ": ";
int flag = 0;
for (int j = 0; j < 7; j++)
{
if (flag)
break;
string now = b[i].substr(j);
if (mp[now].size() != 0)
{
flag = 1;
for (int k = 0; k < mp[now].size(); k++)
{
for (int p = 0; p < j; p++)
cout << b[i][p];
if (j != 0)
cout << "-";
cout << a[mp[now][k]] << " ";
}
}
}
if (!flag)
{
cout << "No words";
}
}
return 0;
}