您的位置:首页 > 编程语言 > C语言/C++

Codeforces Round #285(Div.2) A,B,C 解题报告

2015-08-20 23:18 393 查看
转载请注明出处,谢谢:

http://blog.csdn.net/wybluewind/article/details/47818925

codeforces 上的题解:http://codeforces.com/blog/entry/15743

A. Contest

题目大意:

Codeforces比赛中,Misha在c分钟过了a分的题,Vasya在d分钟过了b分的题。最终的得分的计算方法:max(3p/10, p-pt/250)[在t分钟过了p分的题];

思路:

简单,带入公式算一下就行,注意:不是int类型。

代码:

#incl
4000
ude<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

double a,b,c,d;
double m,v;

int main()
{
//    freopen("in.txt","r",stdin);
while(cin >> a >> b >> c >> d){
m = max(3*a/10,a-a*c/250);
v = max(3*b/10,b-b*d/250);
if(m>v)
printf("Misha\n");
else if(v>m)
printf("Vasya\n");
else printf("Tie\n");
}
return 0;
}


B. Misha and Changing Handles

题目大意:

改名字,只有没用过的新名字才可以改,可以改多次。找出最少改了一次的人的最开始的名字和最后改好的名字。

思路:

首先判断,每一次更改能否成功,把不能修改的记录去掉「状态置为false」。并把用过的名字记录对应到他们的id,这样后面方便查找。从1开始处理,找到一个名字,看他的新名字是否有更改记录,如果有继续向下查找,直到没有修改记录。在向下查找的过程中把用过记录删掉「即把状态置为false」。

代码:

#include<iostream>
#include<cstdio>
#include<map>
#include<string>
#include<cstring>
#include<utility>
using namespace std;

int q;
struct Node{
string old,news;
bool is;
Node(){old=""; news=""; is=true;}
}req[1009];
string old,news;

map<string, int> used;
map<string, string> ans;

int main()
{
//    freopen("in.txt","r",stdin);
while(cin >> q){
for(int i=1; i<=q; ++i){
cin >> old >> news;
req[i].old=old;
req[i].news=news;
req[i].is = true;
}
used.clear();
for(int i=1; i<=q; ++i){
used[req[i].old]=i;
if(used.count(req[i].news)==0){
used[req[i].news]=1009;
}
else{
req[i].is=false;
}
}
ans.clear();
for(int i=1; i<=q; ++i){
if(req[i].is){
news = req[i].news;
while(used[news]<=q && used[news]>0 && req[used[news]].is){
req[used[news]].is= false;
news=req[used[news]].news;
}
ans[req[i].old]=news;
}
}
cout << ans.size() << endl;
for(map<string, string>::iterator it=ans.begin(); it!=ans.end(); ++it)
cout << it->first << " " << it->second << endl;
}

return 0;
}


C. Misha and Forest

题目大意:

一个无环且没有平行边的图,统计每个节点的所连边的个数和节点编号的异或(XOR)和。根据每个节点的所连边的个数和节点编号的异或和,还原图。

思路:

这个图就是树,所以从所连边数是1的节点开始入手,并把这个边从记录的信息中删除(两个点都要删除),即:degree要减1,s要异或这个节点的值。记录一下边的信息输出就可以了。由于数据量大,不建议用c++的输入输出。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;

struct Node{
int from;
int deg;
int s;
Node(){from=0;deg=0; s=0;}
inline bool operator < (const Node &a) const{
if(deg!=a.deg)
return deg<a.deg;
else return s<a.s;
}
}info[(1<<16)+9];
int n;

vector<int> g[(1<<16)+9];
int mp[(1<<16)+9];

int main()
{
//    freopen("in.txt","r",stdin);
while(scanf("%d", &n)!=EOF){
for(int i=0; i<n; ++i)
g[i].clear();

for(int i=0,deg,s; i<n; ++i){
scanf("%d %d", °, &s);
info[i].from = i;
info[i].deg = deg;
info[i].s = s;
}
sort(info,info+n);
for(int i=0; i<n; ++i){
mp[info[i].from] = i;
}
int ans=0;
bool flg=true;
while(true){
flg = true;
for(int i=0; i<n; ++i){
if(info[i].deg == 1){
g[info[i].from].push_back(info[i].s);
info[i].deg = 0;
ans++;
int id = mp[info[i].s];
info[id].deg--;
info[id].s = info[id].s ^ info[i].from;
flg= false;
}
}
if(flg)
break;
}
printf("%d\n",ans);
for(int i=0; i<n; ++i){
for(int j=0; j<g[i].size(); ++j){
printf("%d %d\n",i,g[i][j]);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息