奋斗群群赛19总结与心得

来源:互联网 发布:软件开发java 高级证书 编辑:程序博客网 时间:2024/05/18 13:12

  • 总体情况
  • T1
    • 思路
  • T2
    • 思路
  • T3
    • 思路
  • T4
    • 思路
  • T5
    • 思路

总体情况

老师再一次对我们相当不友好,把比赛的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;//一言不合定义一个nicovector<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-1dfs(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 doubleint 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);}
原创粉丝点击