Link:

Codeforces #190 传送门

A:

明显答案为$n+m-1$且能构造出来

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
int n,m; int main()
{
scanf("%d%d",&n,&m);
printf("%d\n",n+m-);
for(int i=;i<=m;i++)
printf("1 %d\n",i);
for(int i=;i<=n;i++)
printf("%d 1\n",i);
return ;
}

Problem A

B:

我是采取对余数分类讨论的方式

但如果余数为0,2,2且原数中恰好有一个0时要特判!因此WA了一次……

不过完全可以通过采取其他方法来避免这个问题:

暴力枚举散装分别为0,1,2时的总个数即可

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
int r,g,b,tr,tg,tb,res; int main()
{
scanf("%d%d%d",&r,&g,&b);
res+=r/;res+=g/;res+=b/;
tr=r;tg=g;tb=b;
r%=;g%=;b%=;
if(r>g) swap(r,g);
if(r>b) swap(r,b);
if(g>b) swap(g,b); if(r==) res++;
else if(r==) res+=;//如果%3=0的值原来就是0不能增加!
else if(r==&&g==&&b==&&tr&&tg&&tb) res++;
printf("%d",res);
return ;
}

Problem B

C:

此题只要对第一次循环中的所有位置判断能否通过整的循环到达终点即可

不过有2点要注意:1、特判整循环最终$X,Y$为0的情况 2、循环数非负

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
const int INF=<<;
P cur,sum,T;char s[]; void move(P &v,int pos)
{
if(s[pos]=='U') v.Y++;
if(s[pos]=='D') v.Y--;
if(s[pos]=='L') v.X--;
if(s[pos]=='R') v.X++;
}
int main()
{
scanf("%d%d%s",&T.X,&T.Y,s);
if(T==P(,)) return puts("Yes"),; int len=strlen(s);bool f=;
for(int i=;i<len;i++) move(sum,i);
for(int i=;i<len;i++)
{
move(cur,i);//可能mod出-1,因此初始值设为INF
int mx=INF,my=INF,cx=INF,cy=INF;
if(sum.X) mx=(T.X-cur.X)%sum.X,cx=(T.X-cur.X)/sum.X;
if(sum.Y) my=(T.Y-cur.Y)%sum.Y,cy=(T.Y-cur.Y)/sum.Y;
if(mx==INF&&my==INF&&cur==T){f=;break;}
if(mx==INF&&cur.X==T.X&&!my&&cy>=){f=;break;}
if(my==INF&&cur.Y==T.Y&&!mx&&cx>=){f=;break;}
if(!mx&&!my&&cx==cy&&cx>=){f=;break;}
}
puts(f?"Yes":"No");
return ;
}

Problem C

这题一开始都WA了一次……

原因是判断整循环的$X,Y$为0时是用余数的初始值是否为-1来判断的

但实际上余数结果本来就可能是-1从而和初始值冲突

以后对余数设初始值时要注意设为$INF$这样不可能达到的值……

D:

很容易的贪心,发现只要考虑两种情况:

1、只攻击$ATK$

2、将$DEF$和$ATK$都攻击完

将3个序列都排序后

对于情况1,每次用最大的攻击$ATK$最小的,直到不能攻击为止必是最优解

对于情况2,先用尽可能接近的攻击完$DEF$,接下来只要能将$ATK$都打完结果就是两个序列和的差

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
#define pb push_back
typedef long long ll;
typedef double db;
typedef pair<int,int> P;
const int MAXN=;
char s[MAXN];
int n,m,x;
vector<int> atk,def,dat; int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%s%d",s,&x);
if(s[]=='A') atk.pb(x);
if(s[]=='D') def.pb(x);
}
for(int i=;i<=m;i++) scanf("%d",&x),dat.pb(x);
sort(dat.begin(),dat.end());
sort(atk.begin(),atk.end());
sort(def.begin(),def.end()); int res1=,res2=,sum1=,sum2=;bool f=;
for(int i=;i<atk.size()&&i<dat.size();i++)
if(dat[m-i-]>=atk[i]) res1+=dat[m-i-]-atk[i];
else break;
for(int i=(int)def.size()-;i>=;i--)
{
vector<int>::iterator it=upper_bound(dat.begin(),dat.end(),def[i]);
if(it==dat.end()){f=;break;}
dat.erase(it);
}
int sz=dat.size();
if(sz<atk.size()) f=;
for(int i=;i<sz;i++) sum1+=dat[i];
for(int i=;i<atk.size();i++) sum2+=atk[i];
for(int i=(int)atk.size()-;i>=;i--)
{
vector<int>::iterator it=lower_bound(dat.begin(),dat.end(),atk[i]);
if(it==dat.end()){f=;break;}
dat.erase(it);
} res2=f?sum1-sum2:;
printf("%d",max(res1,res2));
return ;
}

Problem D

注意在情况2的第二个阶段不能采取和情况1相同的方法

因为此时的目标是将$ATK$都打完,因此应和攻击$DEF$时采取的方法一样:贪心选取第一个更大的数

E:

构造题

一般在树上构造考虑两种方式:

1、从底到上(对应此题为点分治的方法)

2、从顶至下(从叶子节点向上递归)

方法1:

发现如果将一个节点设为$A$,那么剩下的子树都变成了独立的问题,只不过不能再出现$A$

因此考虑将第$i$层点分治的树根设为$A+i$,这样保证有解因为$log(1e5)<26$

方法2:

考虑从叶子节点向上递归构造

每次向上传递该点的值和该子树中比根大的值,因为比根小的明显不用考虑了

选择时将儿子上传的值合并,选取比出现2次大的第一个没有出现的值

其实就是不合法的值分类后去除:

1、点对在两个不同儿子且值更大(因此选取比出现2次大的)

2、该点本身和子树中一个较大的值组成点对(因此选取为出现过的)

注意在返回时要将比选取值小的个数清零,因为后面不用考虑了

这样保证使用个数不超过26的正确性可以用势能法证明,然而我并不会

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e5+;
struct edge{int nxt,to;}e[MAXN<<];
int n,x,y,head[MAXN],cnt[MAXN][],res[MAXN],tot; void add(int from,int to)
{e[++tot].nxt=head[from];e[tot].to=to;head[from]=tot;}
void dfs(int x,int anc)
{
for(int i=head[x];i;i=e[i].nxt)
{
if(e[i].to==anc) continue;
dfs(e[i].to,x);
for(int j=;j<;j++)
cnt[x][j]+=cnt[e[i].to][j];
}
int pos1=,pos2=;
for(int i=;i<;i++)
if(cnt[x][i]>=){pos1=i;break;}
for(int i=pos1-;i>=;i--)
if(!cnt[x][i]){pos2=i;break;}
cnt[x][pos2]=;res[x]=pos2;
for(int i=pos2+;i<;i++) cnt[x][i]=;
} int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
scanf("%d%d",&x,&y),add(x,y),add(y,x);
dfs(,);
for(int i=;i<=n;i++)
printf("%c ",'A'+res[i]);
return ;
}

Problem E

[Codeforces #190] Tutorial的更多相关文章

  1. [Codeforces #172] Tutorial

    Link: Codeforces #172 传送门 A: 一眼看上去分两类就可以了 1.每个矩形只有两条边相交,重合的形状为菱形 2.每个矩形四条边都有相交 对于情况1答案为$h*h/sin(a)$ ...

  2. [Codeforces #514] Tutorial

    Link: Codeforces #514 传送门 很简单的一场比赛打崩了也是菜得令人无话可说…… D: 一眼二分,发现对于固定的半径和点,能包含该点的圆的圆心一定在一个区间内,求出区间判断即可 此题 ...

  3. [Codeforces #210] Tutorial

    Link: Codeforces #210 传送门 A: 贪心,对每个值都取最大值,不会有其他解使答案变优 #include <bits/stdc++.h> using namespace ...

  4. [Codeforces #196] Tutorial

    Link: Codeforces #196 传送门 A: 枚举 #include <bits/stdc++.h> using namespace std; #define X first ...

  5. [Codeforces #174] Tutorial

    Link: Codeforces #174 传送门 A: 求原根的个数,有一条性质是原根个数为$\phi(\phi(n))$,多了一个不会证的性质 如果要确定哪些是原根的话还是要枚举,不过对于每个数不 ...

  6. [Codeforces #211] Tutorial

    Link: Codeforces #211 传送门 一套非常简单的题目,但很多细节都是错了一次才能发现啊…… 还是不能养成OJ依赖症,交之前先多想想corner case!!! A: 模拟,要特判0啊 ...

  7. [Codeforces #192] Tutorial

    Link: Codeforces #192 传送门 前两天由于食物中毒现在还要每天挂一天的水 只好晚上回来随便找套题做做找找感觉了o(╯□╰)o A: 看到直接大力模拟了 但有一个更简便的方法,复杂度 ...

  8. [Codeforces #201] Tutorial

    Link: 传送门 代码量很少的一套思维题 A: 试一试发现最后状态一定是所有$min,max$间$gcd$的倍数 直接判断数量的奇偶性即可 #include <bits/stdc++.h> ...

  9. [Codeforces #188] Tutorial

    Link: Codeoforces #188 传送门 A: 先全转为正数,后面就全是指数级增长了 #include <bits/stdc++.h> using namespace std; ...

随机推荐

  1. python学习笔记(八)之元组

    元组:和列表十分相似,可以说是一个受限的列表.最大的限制是,元组不能更改. 创建元组 >>> tuple1 = (123,'asd',(1,2,3)) >>> tu ...

  2. canvas_简单练习

    效果图 实现原理: 1.定义canvas标签. 2.获取canvas标签节点,创建canvas2D. 3.在canvas进行画图. 效果代码: <!DOCTYPE html> <ht ...

  3. poj 2000 Gold Coins

    题目链接:http://poj.org/problem?id=2000 题目大意:求N天得到多少个金币,第一天得到1个,第二.三天得到2个,第四.五.六天得到3个....以此类推,得到第N天的金币数. ...

  4. Open Compute Project

    Open Compute Project https://github.com/opencomputeproject https://github.com/floodlight/floodlight ...

  5. Mac OSX下Appium驱动iPhone真机

    1.安装Xcode.Command Line Tools和Appium. 2.安装brew:/usr/bin/ruby -e "$(curl -fsSL https://raw.github ...

  6. C++中delete和delete[]的区别(转)

    原文链接:http://www.cnblogs.com/charley_yang/archive/2010/12/08/1899982.html 一直对C++中的delete和delete[]的区别不 ...

  7. 实现atoi函数

    atoi函数最关键的地方是想好测试用例: 输入为空字符串,输出为0; 输入字符串大小超过INT_MAX输出INT_MAX; 输入字符串大小小于INT_MIN输出INT_MIN; 输入字符串中含有不规则 ...

  8. CentOS下配置FTP

    http://www.cnblogs.com/zhenmingliu/archive/2012/04/25/2470646.html 常见错误: 1.FTP服务器已经拒绝 解决方案 # setenfo ...

  9. 步骤一:下载jdk并安装和配置java环境变量

    1.下载JDk地址: http://download.eclipse.org/oomph/jre/?vm=1_1_7_0_64_0 2.进入下载页面(下载的是jdk7),点击:Oracle JDK1. ...

  10. 《逐梦旅程 WINDOWS游戏编程之从零开始》笔记2——透明贴图,动画技术

    第5章 透明贴图 像这样直接贴图会产生这种情况,所以我们需要透明贴图. 透明遮罩法:主要利用BitBlt函数中Raser(光栅)值的运算,需要准备素材图和遮罩图: 这个方法的原理解释见书131页. 示 ...