总体情况
老师再一次对我们相当不友好,把比赛的A题换成了一道C题.今天我是真的爆零了,非常遗憾E本是一道非常水的并查集,我却WA了第3个点.
所有题目如下:
A:http://codeforces.com/problemset/problem/200/C
B:http://codeforces.com/problemset/problem/198/B
C:http://codeforces.com/problemset/problem/195/C
D:http://codeforces.com/problemset/problem/195/D
E:http://codeforces.com/problemset/problem/195/E
T1
思路
足球比赛,理论暴枚.但是真的很难.不知道下面的代码大家能不能看懂,很多神一般的操作,能解释的我解释一下.
#include<bits/stdc++.h>
#define r "BERLAND"//看见"BERLAND"老子就烦,一定看清楚
using namespace std;
int main()
{
map<string,int> defen,jishu,yingqiu,shuqiu;//排序的时候按照得分,净胜球以及以及进球个数进行,计数即该队伍在比赛的时候已经出现过多少次,扫一下看看哪个队伍最后和BERLAND打一场
int x,y,i;char a[28],b[28];
for (i=0;i<5;i++)
{
scanf("%s%s%d:%d",a,b,&x,&y);
jishu[a]++,jishu[b]++;
if (x>y) defen[a]+=3;
if (x<y) defen[b]+=3;
if (x==y) defen[a]++,defen[b]++;
yingqiu[a]+=x,shuqiu[a]+=y;
yingqiu[b]+=y,shuqiu[b]+=x;
}//这些不用解释吧
string nico;//一言不合定义一个nico
vector<string> duiwu;
for (auto &s:jishu)//简单粗暴
{
duiwu.push_back(s.first);
if (s.second==2&&s.first!=r) nico=s.first;//让这支队伍和BERLAND打一场
}
for (i=1;i<100;i++) for (int j=0;j<100;j++)//i是净胜球的数量,j是输球的数量
{
int k=i+j;
yingqiu[r]+=k,shuqiu[r]+=j,defen[r]+=3;//这样能看懂吧,赢球多k
yingqiu[nico]+=j,shuqiu[nico]+=k;//所以对方输球多k
vector<tuple<int,int,int,string> > v;//百度搜一下tuple,c++11新增数据结构
for (auto &s:duiwu) v.push_back(make_tuple(-defen[s],-yingqiu[s]+shuqiu[s],-yingqiu[s],s));//排序的时候从小到大,放进去的时候用负数,出来的时候可以从大到小
sort(v.begin(),v.end());
if (get<3>(v[0])==r||get<3>(v[1])==r) return printf("%d:%d",k,j),0;//说明BERLAND晋级了
defen[r]-=3,yingqiu[r]-=k,shuqiu[r]-=j;//get<3>是找tuple中的第3个数据
yingqiu[nico]-=j,shuqiu[nico]-=k;//也算回溯的一种
}
printf("IMPOSSIBLE");
}
T2
思路
这个东西大法师一下吗,不就搞定了.当时在做的时候突然傻x了,忘记了不需要回扫已经走过的位置,于是TLE20个点.后来加了个记忆化搜索就成了最短的代码.貌似这题宽搜也可以,不过肯定是深搜要短了.
#include<bits/stdc++.h>
using namespace std;
string s[2];int n,k;bool jumped[2][100020];
void dfs(int lor,int p,int t)//左或右,走到的位置,水已经漫上的位置
{
if (s[lor][p]=='X'||p<=t||jumped[lor][p]) return;//走到危险的位置,水漫出的位置,已经走过的位置
if (p>n-k) {printf("YES");exit(0);}//比n-k大,直接一跳出去了
jumped[lor][p]=1;
dfs((lor+1)%2,p+k,t+1);
dfs(lor,p+1,t+1);
dfs(lor,p-1,t+1);
}
int main()
{
cin>>n>>k>>s[0]>>s[1];n--;//字符串最大位置是n-1
dfs(0,0,-1);
printf("NO");
}
T3
思路
暴力模拟,没有想到CF大神的代码能如此之骚.好像这里用了一下scanf特殊技巧.我做个解释,就是带有中括号的是一个集合,先是一个^把不属于该集合的元素无视掉,然后再读入,这样就能无视掉前面的空格了.
欣赏吧.
#include<bits/stdc++.h>
using namespace std;
char s[100],p[100],l[100],r[100],w[100]={"Unhandled Exception"};int n;bool nico;//由于不知道它是什么变量,就定义nico,简单
bool judge()
{
bool fuko=0;//这里fuko的定义同理
while (scanf("%*[^a-z]%[a-z]",s),s[1]!='a')
{
if (s[1]=='r') fuko|=judge();
if (s[1]=='h') scanf("%*[^A-Za-z]%[A-Za-z]",p),fuko=1;
}
scanf("%*[^A-Za-z]%[A-Za-z]",l),scanf("%*[^\"]\"%[^\"]",r);
if (fuko&&!nico&&strcmp(l,p)==0) nico=true,strcpy(w,r);
return fuko;
}
int main()
{
scanf("%d",&n);
while (scanf("%*[^a-z]%[a-z]",s)!=EOF&&s[1]=='r') judge();
printf("%s",w);
}
T4
思路
输入的函数形成一条折线,找到里面非180度角的数目.这题看看代码就是送的.注意用scanf,现在我见识到cin有多慢,90000多个数就T了.
#include<bits/stdc++.h>
#define z long double
int n,a,k,b;
std::map<z,bool> m;
int main()
{
for (scanf("%d",&n);n--;)
{
scanf("%d%d",&k,&b);
if (k&&!m[(z)b/k]) m[(z)b/k]=1,a++;
}
std::cout<<a;
}
T5
思路
超级水的并查集.本来我觉得我有水平能写出来的,结果因为重复更新后缀和WA了第3个点.超级惨.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,map<ll,ll> > lujing;
const ll mod=1e9+7;
ll n,k,father[100010],answer;
ll find(ll x){return father[x]==x?x:find(father[x]);}
void merge(ll a,ll b,ll t)
{
a=find(a);
father[a]=b;
lujing[a][b]=t;
}
ll depth(ll x)
{
ll p=x,r;
while (x!=father[x])
{
r=lujing[x][father[x]];
x=father[x];
lujing[x][father[x]]+=r;
}
return r;
}
int main()
{
ll i,j;
ios::sync_with_stdio(0);cin.tie(0);
cin>>n;
for (i=1;i<=n;i++) father[i]=i;
for (i=1;i<=n;i++)
{
cin>>k;
for (j=1;j<=k;j++)
{
ll u,v;
cin>>u>>v;
merge(u,i,v);
answer=(answer+depth(u))%mod;
}
}
cout<<answer;
}
所以我去瞄了一眼大佬的代码.真的太强了.
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7,boss=1e5;
int fa[boss+10],len[boss+10],n,m,v,x,i,j,answer,t;
int find(int x)
{
if (fa[x]==x) return x;
int t=fa[x];fa[x]=find(fa[x]);
len[x]=(len[x]+len[t])%mod;
return fa[x];
}
int main()
{
for (scanf("%d",&n),i=1;i<=n;fa[i]=i,i++) for (scanf("%d",&m);m--;t=find(v),answer=(answer+(len[v]+x)%mod)%mod,fa[t]=i,len[t]=(len[v]+x)%mod) scanf("%d%d",&v,&x);
printf("%d",(answer+mod)%mod);
}