2015年的icpc英国站,不到一百只过题队伍,可以算是icpc在英国刚起步的时候。
Problem B Mountain Biking
思路:作为本场的签到题,读懂题意之后,这题倒是更像一道数学题。给定n个坡面的角度,求解到达坡道底端的速度
利用经典力学动力学公式
即可直接求出.
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e7+5;
const double pi = 3.1415926;
int a[maxn];
int main()
{
int n;
//freopen(".txt","r",stdin);
//ios::sync_with_stdio(false);
//cin.tie(0);
//cout << cos(60.0/180.0*pi) << endl;
double g,x[5],a[5],v0=0.0,re[5];
scanf("%d%lf",&n,&g);
for(int i=0;i<n;i++) scanf("%lf%lf",&x[i],&a[i]);
for(int i=n-1;i>=0;i--)
{
double dv2 = 2.0 * g * cos(pi*a[i]/180.0) * x[i];
double v2 = v0 + dv2;
re[i] = sqrt(v2);
v0 = v2;
}
for(int i=0;i<n;i++)
printf("%.7lf\n",re[i]);
return 0;
}
Problem C Conversation Log
思路:字符串处理的题目,统计用户发送的单词,记录所有用户均发送过的单词,并排序。毫无疑问,事先构造两个表,来存储姓名和单词。之后模拟聊天过程,记录每个用户发送的单词,最后检验单词是否被每个用户都发送过,排序后,在对照反向单词表将单词复原打印
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e4;
map <string,int> nametable;
map <string,int> wordtable;
string findword[maxn];
int record[maxn][maxn];
typedef struct result
{
int rk;
string me;
}Result;
bool cmp(const Result &a, const Result &b)
{
if(a.rk>b.rk)
return true;
else if(a.rk==b.rk&&a.me<b.me)
return true;
else
return false;
}
vector<Result> r;
int main()
{
int n;
//freopen("in.txt","r",stdin);
//ios::sync_with_stdio(false);
//cin.tie(0);
scanf("%d\n",&n);
int namenum = 0;
int wordnum = 0;
memset(record, 0, sizeof record);
r.clear();
while(n--)
{
string s;
getline(cin,s);
int len = s.size();
int pos;
for(pos=0;pos<len;pos++)
if(s[pos]==' ')
break;
string name = s.substr(0,pos);
if(nametable.count(name)==0)
nametable[name] = namenum++;
pos++;
for(int i=pos;i<len;i++)
{
if(s[i]==' ')
{
string word = s.substr(pos,i-pos);
if(wordtable.count(word)==0)
{
wordtable[word] = wordnum;
findword[wordnum++] = word;
//cout << word << "##" <<endl;
}
record[nametable[name]][wordtable[word]]++;
pos = i+1;
}
}
string word = s.substr(pos,len-pos);
if(wordtable.count(word)==0)
{
wordtable[word] = wordnum;
findword[wordnum++] = word;
}
record[nametable[name]][wordtable[word]]++;
}
for(int i=0;i<wordnum;i++)
{
bool ok = true;
int sum = 0;
for(int j=0;j<namenum;j++)
{
if(record[j][i] > 0)
sum += record[j][i];
else
{
//cout << findword[i] <<"*"<<endl;
ok = false;
break;
}
}
if(ok)
{
Result temp;
temp.rk = sum;
temp.me = findword[i];
r.push_back(temp);
}
}
sort(r.begin(),r.end(),cmp);
int renum = r.size();
//cout << wordnum << endl;
//cout << namenum <<endl;
//cout << renum << endl;
/*for(map<string,int> :: iterator it = nametable.begin();it!=nametable.end();it++)
cout << it->first << "&" <<it->second<< endl;
for(map<string,int> :: iterator it = wordtable.begin();it!=wordtable.end();it++)
cout << it->first << "&" <<it->second<< endl;
for(int i=0;i<5;i++)
{
for(int j=0;j<7;j++)
printf("%d ",record[i][j]);
printf("\n");
}
for(int i=0;i<wordnum;i++)
cout << findword[i] <<"%"<< endl;*/
if(renum==0)
cout << "ALL CLEAR\n";
else
{
for(int i=0;i<renum;i++)
cout << r[i].me << '\n';
}
return 0;
}
Problem I Nimionese
思路:又是个字符串处理的题目,当然这题就是个大模拟。
将字母分入两个集合(hard集和非hard集),然后根据几个限制变更一下字符串
字符串由单词和后续单词段组成,单词首字母可能为大写字母,其余字母均必为小写字母
变更规则如下:
单词首字母变更为hard字母
后续单词段中的hard字母变更为该单词首字母,并删去连词符
若单词结尾为hard字母,则增加对应的非hard字母,并增加语气字母h
小小的坑点就在于大小写的判断上
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
map <char,char> h;
map <char,char> he;
vector <char> re;
int main()
{
h['a']='b';
h['e']='d';
h['f']='g';
h['h']='g';
h['i']='g';
h['j']='k';
h['l']='k';
h['m']='n';
h['o']='n';
h['q']='p';
h['r']='p';
h['s']='t';
h['u']='t';
h['v']='t';
h['w']='t';
h['x']='t';
h['y']='t';
h['z']='t';
he['b']='a';
he['c']='a';
he['d']='a';
he['g']='a';
he['k']='o';
he['n']='o';
he['p']='o';
he['t']='u';
string s;
getline(cin,s);
re.clear();
//cout << s <<"*" << endl;
int len = s.size();
//int pos = 0;
int p = 1;
char st;
for(int now=0;now<len;now++)
{
if(s[now] == ' ')
{
bool up = false;
if(s[now-1]>='A'&&s[now-1]<='Z')
{
up = true;
s[now-1] = s[now-1] - 'A' + 'a';
}
if(he.count(s[now-1]) > 0)
{
re.push_back(he[s[now-1]]);
re.push_back('h');
re.push_back(' ');
}
else
re.push_back(' ');
if(up)
s[now-1] = s[now-1] - 'a' + 'A';
p = 1;
}
else if(s[now] == '-')
p=2;
else if(p == 1)
{
//cout << "***" << endl;
p=0;
bool up = false;
//cout << s[now]<<'$'<<endl;
if(s[now]>='A'&&s[now]<='Z')
{
//cout << s[now]<<'$'<<endl;
up = true;
s[now] = s[now] - 'A' + 'a';
//cout << s[now]<<'%'<<endl;
}
//cout << "***" << endl;
if(h.count(s[now])>0)
s[now] = h[s[now]];
st = s[now];
//cout << "***" << endl;
if(up)
s[now] = s[now] - 'a' + 'A';
re.push_back(s[now]);
//cout << s[now] << "&" << endl;
}
else if(p==2)
{
if(he.count(s[now])>0)
s[now] = st;
//cout << s[now] << "*" <<endl;
//cout << s[now] << "*" <<endl;
re.push_back(s[now]);
}
else
re.push_back(s[now]);
}
bool up = false;
if(s[len-1]>='A'&&s[len-1]<='Z')
{
up = true;
s[len-1] = s[len-1] - 'A' + 'a';
}
if(he.count(s[len-1]) > 0)
{
re.push_back(he[s[len-1]]);
re.push_back('h');
}
if(up)
s[len-1] = s[len-1] - 'a' + 'A';
p = 1;
int num = re.size();
for(int i=0;i<num-1;i++)
cout << re[i];
cout << re[num-1] << '\n';
return 0;
}
Problem M Milestone Counter
思路:这题题意不是很好理解,导致了这题过题率特别低,读懂题目后,其实就是个匹配问题,匀速行驶过若干不同位置的计时点,并记录下时间,求可能的初始起始计时点,这就是一个匹配问题,暴力每个起始点,然后计算速度,若所有速度均相同则成功匹配
/*
Author Owen_Q
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3+5;
const double eps = 1e-9;
ll t[maxn];
ll x[maxn];
set <ll> re;
bool e(double a,double b)
{
if(a-b<eps&&b-a<eps)
return true;
else
return false;
}
int main()
{
int n,m;
//freopen("in.txt","r",stdin);
//ios::sync_with_stdio(false);
//cin.tie(0);
re.clear();
scanf("%d%d",&m,&n);
for(int i=0;i<m;i++) scanf("%lld",&t[i]);
for(int i=0;i<n;i++) scanf("%lld",&x[i]);
for(int p=0;p<=n-m;p++)
{
double v = double(x[p+1]-x[p])/double(t[1]-t[0]);
//cout << v << "&" << p << endl;
bool ok = true;
for(int now=1;now<m-1;now++)
{
double vv = double(x[p+1+now]-x[p+now])/double(t[now+1]-t[now]);
//cout << vv << "&&" <<p + now << endl;
if(!e(v,vv))
{
ok = false;
break;
}
}
if(ok)
{
re.insert(x[p+1]-x[p]);
//cout << x[p+1]-x[p] << "&&&" << endl;
}
}
set<ll> ::iterator it = re.begin();
if(re.empty())
printf("0\n");
else
{
int len = re.size();
printf("%d\n",len);
printf("%lld",*(re.begin()));
it++;
for(; it != re.end();it++)
printf(" %lld",(*it));
printf("\n");
}
return 0;
}

本文回顾了2015年的United Kingdom and Ireland Programming Contest (UKIEPC 2015),重点解析了四道题目:Mountain Biking(涉及经典力学动力学)、Conversation Log(字符串处理和统计)、Nimionese(字符串模拟)以及Milestone Counter(匹配问题)。文章介绍了每道题目的思路和解决策略,帮助读者理解竞赛中的难题。


被折叠的 条评论
为什么被折叠?



