Codeforces Round #199 (Div. 2)
题意:给定N个数,每个数的取值范围为1-7,N是3的倍数,判定是否能够恰好将N个数分成若干三元组,使得一个组中的元素a,b,c满足 a < b < c 并且 a|b && b|c(整除)。
分析:满足这种条件的三元组只有[1, 2, 4], [1, 2, 6], [1, 3, 6]因此如果有5或者是7肯定是不行的,然后是1的个数要等于4和6的个数之和,最后就是2的数量必须4的数量。
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int N = ;
int n;
int cnt[]; int main() {
int x;
bool flag = false;
scanf("%d", &n);
for (int i = ; i < n; ++i) {
scanf("%d", &x);
if (x == || x == ) flag = true;
cnt[x]++;
}
if (flag || cnt[] != cnt[]+cnt[] || cnt[] < cnt[]) {
puts("-1");
return ;
}
for (int i = ; i < cnt[]; ++i) puts("1 2 4");
for (int i = ; i < cnt[]; ++i) puts("1 3 6");
for (int i = ; i < cnt[]-cnt[]; ++i) puts("1 2 6");
return ;
}
题意:有N个人站成一行,现在有一个情报要从编号S传到编号F,每次每个人只能够向左或者向右边的一个人传送。给定一个时间表,某一段时间内某个区间的人使不能够接收和传送情报,要求输出花最小时间的代价的传送方案。
分析:可以得到一个结论,如果S < F,那么情报不可能向左边传,顶多是停在某个人手中,S > F 同理,因此直接模拟即可。
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std; const int M = ;
int n, m, s, f; struct interval {
int l, r, ti;
void read() {
scanf("%d %d %d", &ti, &l, &r);
}
bool judge(int x) {
if (x >= l && x <= r) return false;
else return true;
}
}q[M]; void solve() {
int dir = s < f ? : -;
char ch = s < f ? 'R' : 'L';
int ti = ;
int X = ;
while (s != f) {
++ti;
if (ti == q[X].ti) {
if (q[X].judge(s) && q[X].judge(s+dir)) putchar(ch), s += dir;
else putchar('X');
X++;
} else {
putchar(ch);
s += dir;
}
}
} int main() {
scanf("%d %d %d %d", &n, &m, &s, &f);
for (int i = ; i < m; ++i) {
q[i].read();
}
solve();
return ;
}
题意:问一个橱柜中能够放置多少个球。
分析:其实就是一个分段函数,可以分别在顶端放1个,放2个,放3个的h取值。
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std; int r, h;
const double eps = 1e-; int sign(double x) {
return x < -eps ? - : x > eps ? : ;
} int get(double x) {
if (sign(*x - sqrt()*r) >= ) return ;
else if (sign(*x - r) >= ) return ;
else return ;
} int main() {
scanf("%d %d", &r, &h);
printf("%d\n", h/r* + get(h-h/r*r));
return ;
}
题意:给定一个3*N的棋盘,其中某些位置不能够放置,并且有一个点是空的,问使用1*2的方格来平铺能够有多少种方案,要求一个空格周围有1*2的方格可能移动。
分析:与其他的题目稍有不同的就是棋盘多了一些限制并且有一个点周围的点至少有一个1*2的方格能够移动。对于前者,在dp的时候做个位运算即可,后者我的做法是用总的方案数减去不合法的方案数。
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int mod = int(1e9)+;
vector<int>vt[];
int dp[][];
int mp[];
int ocp[];
int n, cx, cy; void pre() {
vt[].push_back();
vt[].push_back();
vt[].push_back();
vt[].push_back(), vt[].push_back();
vt[].push_back();
vt[].push_back();
vt[].push_back(), vt[].push_back();
vt[].push_back(), vt[].push_back(), vt[].push_back();
} int cal_1() { // 计算全部的情况
dp[][] = ;
for (int i = ; i <= n; ++i) {
for (int j = ; j < ; ++j) {
if ((j & mp[i]) != j) continue;
for (int k = ; k < (int)vt[j].size(); ++k) {
dp[i][j|ocp[i]] = (1LL*dp[i][j|ocp[i]] + dp[i-][vt[j][k]])%mod;
}
}
}
return dp[n][];
} int cal_2() { // 计算非法的情况
memset(dp, , sizeof (dp));
dp[][] = ;
for (int i = ; i <= n; ++i) {
if (i+ == cx) { // 如果是空点的上一行
for (int j = ; j < ; ++j) {
if ((j & mp[i]) != j) continue;
for (int k = ; k < (int)vt[j].size(); ++k) {
if (!(vt[j][k] & ( << cy-))) continue;
dp[i][j|ocp[i]] = (1LL*dp[i][j|ocp[i]] + dp[i-][vt[j][k]])%mod;
}
}
} else if (i == cx) { // 如果是空点的所在行
for (int j = ; j < ; ++j) {
if ((j & mp[i]) != j) continue;
for (int k = ; k < (int)vt[j].size(); ++k) {
if (cy==&&(j&(<<cy-))&&(j&(<<cy-))&&(vt[j][k]&(<<cy-))&&(vt[j][k]&(<<cy-))) continue;
if (cy==&&(j&(<<cy))&&(j&(<<cy+))&&(vt[j][k]&(<<cy))&&(vt[j][k]&(<<cy+))) continue;
dp[i][j|ocp[i]] = (1LL*dp[i][j|ocp[i]] + dp[i-][vt[j][k]])%mod;
}
}
} else if (i- == cx) { // 如果是空点的下数第二行
for (int j = ; j < ; ++j) {
if ((j & mp[i]) != j) continue;
for (int k = ; k < (int)vt[j].size(); ++k) {
if (!(vt[j][k] & ( << cy-))) continue;
dp[i][j|ocp[i]] = (1LL*dp[i][j|ocp[i]] + dp[i-][vt[j][k]])%mod;
}
}
} else {
for (int j = ; j < ; ++j) {
if ((j & mp[i]) != j) continue;
for (int k = ; k < (int)vt[j].size(); ++k) {
dp[i][j|ocp[i]] = (1LL*dp[i][j|ocp[i]] + dp[i-][vt[j][k]])%mod;
}
}
}
}
return dp[n][];
} int main() {
pre();
scanf("%d", &n);
char str[];
for (int i = ; i <= ; ++i) {
scanf("%s", str+);
for (int j = ; j <= n; ++j) {
mp[j] |= (int)(str[j]=='.') << (i-);
ocp[j] |= (int)(str[j]!='.') << (i-);
if (str[j] == 'O') cx = j, cy = i;
}
}
printf("%d\n", (cal_1()-cal_2()+mod)%mod);
return ;
}
题意:给定一棵树,初始化1号节点为红色,其他点为蓝色。有两种操作:1.将某个点从蓝色变成红色;2.询问某个节点到最近的红色的点的距离。
分析:对于1操作保留要改变的点,当有询问时在bfs更新。不过觉得这种做法在树退化成一条链时时间复杂度为O(N^2)。
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef unsigned int uint;
const int N = ;
int dis[N];
char vis[N];
int n, m;
vector<int>vt;
queue<int>q; struct Edge {
int v, nxt;
}e[N<<];
int idx, head[N]; void addedge(int a, int b) {
e[idx].v = b, e[idx].nxt = head[a];
head[a] = idx++;
} void spread() {
memset(vis, , sizeof (vis));
for (uint i = ; i < vt.size(); ++i) {
dis[vt[i]] = ;
vis[vt[i]] = ;
q.push(vt[i]);
}
vt.clear();
while (!q.empty()) {
int u = q.front(); q.pop();
vis[u] = ;
for (int i = head[u]; ~i; i = e[i].nxt) {
int v = e[i].v;
if (dis[v] > dis[u] + ) {
dis[v] = dis[u] + ;
if (!vis[v]) vis[v] = , q.push(v);
}
}
}
} int main() {
int a, b;
idx = ;
memset(head, 0xff, sizeof (head));
memset(dis, 0x3f, sizeof (dis));
scanf("%d %d", &n, &m);
for (int i = ; i < n; ++i) {
scanf("%d %d", &a, &b);
addedge(a, b), addedge(b, a);
}
vt.push_back();
for (int i = ; i < m; ++i) {
scanf("%d %d", &a, &b);
if (a == ) vt.push_back(b);
else spread(), printf("%d\n", dis[b]);
}
return ;
}
Codeforces Round #199 (Div. 2)的更多相关文章
- Codeforces Round #199 (Div. 2) E. Xenia and Tree
题目链接 2了,差点就A了...这题真心不难,开始想的就是暴力spfa就可以,直接来了一次询问,就来一次的那种,TLE了,想了想,存到栈里会更快,交又TLE了..无奈C又被cha了,我忙着看C去了.. ...
- Codeforces Round #199 (Div. 2) A Xenia and Divisors
注意题目的数字最大是7 而能整除的只有 1,2,3,4,6,故构成的组合只能是1,2,4 或1,2,6或1,3,6,故分别统计1,2,3,4,6的个数,然后再分配 #include <iostr ...
- Codeforces Round #199 (Div. 2) B. Xenia and Spies
B. Xenia and Spies time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Round #199 (Div. 2) C. Cupboard and Balloons
C. Cupboard and Balloons time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- Codeforces Round #199 (Div. 2) D. Xenia and Dominoes
把 'O' 看成 'X',然后枚举它的四个方向看看是否能放,然后枚举 $2^4$ 种可能表示每种方向是否放了,放了的话就标成 'X',就相当于容斥,对于新的图去dp. dp就是铺地砖,行用二进制来表示 ...
- Codeforces Round #515 (Div. 3)
Codeforces Round #515 (Div. 3) #include<bits/stdc++.h> #include<iostream> #include<cs ...
- Codeforces Round #366 (Div. 2) ABC
Codeforces Round #366 (Div. 2) A I hate that I love that I hate it水题 #I hate that I love that I hate ...
- Codeforces Round #354 (Div. 2) ABCD
Codeforces Round #354 (Div. 2) Problems # Name A Nicholas and Permutation standard input/out ...
- Codeforces Round #368 (Div. 2)
直达–>Codeforces Round #368 (Div. 2) A Brain’s Photos 给你一个NxM的矩阵,一个字母代表一种颜色,如果有”C”,”M”,”Y”三种中任意一种就输 ...
随机推荐
- Python编程核心之makeTextFile.py和readTextFile.py
引言: 最近大半年都在学习python编程,在双十一的时候购买了<Python编程核心>,看到makeTextFile.py和readTextFile.py两个例子有点错误,所以在这里给修 ...
- MySQL数据类型总结
MySQL中的数据类型大的方面来分,可以分为:日期和时间.数值,以及字符串.下面就分开来进行总结. 日期和时间数据类型 MySQL数据类型 含义 date 3字节,日期,格式:2014-09-18 t ...
- js的作用域
全局代码和两个函数都会形成一个作用域,通过函数是在哪个作用域下创建的来确定作用域的上下级关系.作用域最大的用处是隔离变量,不同作用域下同名变量不会有冲突.
- 鼠标放上去,div高度随文字增加,并显示剩余的文字。
/*这里是鼠标放上去显示全名 */ .kb2wText{display:block; height:20px; width:150px; line-height:20px; color:#0 ...
- Unity帧序列实时渲染脚本
该脚本会创建一个新相机进行录制,支持包含所有相机内容,完美解决跳帧问题,可自定义分辨率等参数,脚本会输出品质为100的jpg序列,基本无损. 但缺点是帧率始终是每秒100帧,必须压制时限制帧数. 而用 ...
- JAVA基础知识之网络编程——-基于NIO的非阻塞Socket通信
阻塞IO与非阻塞IO 通常情况下的Socket都是阻塞式的, 程序的输入输出都会让当前线程进入阻塞状态, 因此服务器需要为每一个客户端都创建一个线程. 从JAVA1.4开始引入了NIO API, NI ...
- 文件映射mmap
磁盘与内存的映射就是文件映射,说这个问题之前我们先说下swap,因为 这个问题让我很容易想起swap,linux swap 是交换分区的意思,在内存不 够的情况下,操作系统先把内存与磁盘的sw ...
- Repeater的Command操作
Repeater的Command操作 1.ItemCommand事件 :在Repeater中所有能触发事件的控件,都会来触发这一个事件 后台创建:在Page_Load中 Repeater1.ItemC ...
- Xcode插件管理以及Xcode7 升级
一,Xcode插件管理工具 Alcatraz: mkdir -p ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-ins; cur ...
- 【leetcode❤python】171. Excel Sheet Column Number
#-*- coding: UTF-8 -*- # ord(c) -> integer##Return the integer ordinal of a one-character string. ...