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. 【BZOJ】3329: Xorequ

    [题意]给定方程x^3x=2x,求<=x和<=2^x的满足方程的正整数个数. [算法]数位DP,矩阵快速幂 [题解]异或相当于不进位加法. 移项得,x^2x=3x,又因为x+2x=3x,所 ...

  2. SpringBoot Mybatis 读写分离配置(山东数漫江湖)

    为什么需要读写分离 当项目越来越大和并发越来大的情况下,单个数据库服务器的压力肯定也是越来越大,最终演变成数据库成为性能的瓶颈,而且当数据越来越多时,查询也更加耗费时间,当然数据库数据过大时,可以采用 ...

  3. Android中的异常情况

    1.setText()方法中,如果参数是int类型,Android会把它当做是一个id查找,报以下异常,因此解决办法就是将参数转化为String类型 如:setText(num) è setText( ...

  4. Spring Cloud Eureka服务注册源码分析

    Eureka是怎么work的 那eureka client如何将本地服务的注册信息发送到远端的注册服务器eureka server上.通过下面的源码分析,看出Eureka Client的定时任务调用E ...

  5. 如何修改或美化linux终端

    先丢一张效果图: 如何让您的 LD 的终端更具个性呢?首先,我们需要了解下面几点知识.A:配置文件 个人配置文件:~/.bashrc全局设定文件:/etc/bash.bashrc(修改需要管理员权限) ...

  6. JavaScript match() 方法

    match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配. 该方法类似 indexOf() 和 lastIndexOf(),但是它返回指定的值,而不是字符串的位置. var st ...

  7. 原始套接字&&数据链路层访问

    1. 原始套接字能力: (1) 进程可以读写ICMP,IGMP等分组,如ping程序: (2) 进程可以读写内核不处理协议字段的ipv4数据报:如OSPF等: (3) 进程可以使用IP_HDRINCL ...

  8. Linux 入门记录:十三、Linux 扩展权限

    一.默认权限 每一个终端都有一个 umask 属性,是用来确定新建文件或目录的默认权限的“掩码”(mask 有“掩码”的含义,至于 u,后面说). Linux 中一般有默认的权限掩码,使用命令 uma ...

  9. Meld:文件及目录对比工具

    Meld:文件及目录对比工具 http://wowubuntu.com/meld.html http://meld.sourceforge.net/

  10. 【bzoj4567】SCOI2016背单词

    题号莫名喜感. 倒序建Trie,dfs这棵Trie,贪心一下,每次按照size排序计算贡献就好. #include<bits/stdc++.h> #define N 100010 #def ...