您的位置:首页 > 其它

Codeforces Round #264 (Div. 2)

2014-08-30 19:52 330 查看
题目:
LINK

A。 水题,不多说。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define INF 1000000000
//typedef __int64 LL;
int n, s;
int x, y;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
scanf("%d%d", &n, &s);
int ans = -INF;
for(int i = 1; i <= n; i++) {
scanf("%d%d", &x, &y);
if(x > s) continue;
if(x == s && y) continue;
if(y == 0) ans = max(ans, 0);
else ans = max(ans, 100 - y);
}
if(ans < 0) printf("-1\n");
else printf("%d\n", ans);

return 0;
}

B。 遍历一遍,就可以了.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define INF 1000000000
//typedef __int64 LL;
#define N 100005
int hh
, n;
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d", &n);
hh[0] = 0;
for(int i = 1; i<=n; i++) {
scanf("%d", &hh[i]);
}
int ans = 0;
int now = 0;
for(int i = 1; i<=n; i++){
if(hh[i-1] >= hh[i]) {
now += hh[i-1] - hh[i];
}
else {
int tmp = hh[i] - hh[i-1];
if(now >= tmp) {
now -= tmp;
}
else {
ans += tmp - now;
now = 0;
}
}
}
printf("%d\n", ans);
return 0;
}

C. 可以看成DP吧,其实就是预处理出来每个点四个方向过来的总和。每个点的和为四个方向加起来

如果两个点,满足条件等价于两点的 横坐标之差,和纵坐标之差,有且仅有一个为奇数.

按照坐标的奇偶可以分为四类点,处理出来每一类的最值,和最值的坐标。之后 在满足条件的点的组合中取最大值就可以了. 注意这组数据就可以了

2

0 0

0 0

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define INF 1000000000
typedef __int64 LL;
#define N 2005
LL n;
LL num

, dp1

, dp2

, dp3

, dp4

, dp

;
LL ma[10];
struct node {
int x, y;
}gg[10];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%I64d", &n);
for(LL i = 1; i<=n; i++) {
for(int j = 1; j <= n; j++) {
scanf("%I64d", &num[i][j]);
}
}
for(int i = 1; i<=n; i++) {
for(int j = 1; j<=n; j++) {
dp1[i][j] = dp1[i-1][j-1] + num[i][j];
}
}
for(int i = 1; i<=n; i++) {
for(int j = n; j>=1; j--) {
dp2[i][j] = dp2[i-1][j+1] + num[i][j];
}
}
for(int i = n; i>=1; i--) {
for(int j = 1; j<=n; j++) {
dp3[i][j] = dp3[i+1][j-1] + num[i][j];
}
}
for(int i = n; i>=1; i--) {
for(int j = n; j>=1; j--) {
dp4[i][j] = dp4[i+1][j+1] + num[i][j];
}
}
for(int i = 1; i<=n; i++) {
for(int j = 1; j<= n; j++) {
dp[i][j] = dp1[i][j] + dp2[i][j] + dp3[i][j] + dp4[i][j] - num[i][j] * 3;
int ii = i&1;
int jj = j&1;
int s = (ii<<1) | jj;
if(dp[i][j] >= ma[s]) {
ma[s] = dp[i][j]; gg[s].x = i; gg[s].y = j;
}
}
}
LL ans = 0;
int x1, y1, x2, y2;
if(ma[0] + ma[1] >=ans) {
ans = ma[0] + ma[1]; x1 = gg[0].x; y1 = gg[0].y;
x2 = gg[1].x; y2 = gg[1].y;
}
if(ma[0] + ma[2] >= ans) {
ans = ma[0] + ma[2]; x1 = gg[0].x; y1 = gg[0].y;
x2 = gg[2].x; y2 = gg[2].y;
}
if(ma[3] + ma[1] >=ans) {
ans = ma[3] + ma[1]; x1 = gg[3].x; y1 = gg[3].y;
x2 = gg[1].x; y2 = gg[1].y;
}
if(ma[3] + ma[2] >=ans) {
ans = ma[3] + ma[2]; x1 = gg[3].x; y1 = gg[3].y;
x2 = gg[2].x; y2 = gg[2].y;
}
printf("%I64d\n", ans);
printf("%d %d %d %d\n", x1, y1, x2, y2) ;
return 0;
}


D. 给你k个长度为n的1~n的排列,求这k个的最长公共子序列. 发现 k 很小, 而且序列是n的排列, 注意这两个条件.

dp[i] 表示以第一个序列为参考,以第i个位置为终点的LCS的长度.

dp[i] = dp[j] + 1 ,if 第一个序列中num[j] num[i] (j<i)在所有序列中都满足num[i] 在 num[j]前面.

结果ans = max(dp[1~n]); 

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
#define INF 1000000000
#define N 7
#define M 1010
int a
[M], b
[M], n, k, dp[M];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
scanf("%d%d", &n, &k);
int tmp ;
for(int i = 1; i <= k; i++) {
for(int j = 1; j<= n; j++) {
scanf("%d", &tmp); a[i][j] = tmp; b[i][tmp] = j;
}
}
int ans = 0;
for(int i = 1; i <= n; i++) {
dp[i] = 1;
for(int j = 1; j < i ; j++) {
int flag = 0;
for(int ii = 2; ii <= k; ii ++) {
if(b[ii][a[1][i]] < b[ii][a[1][j]]) flag = 1;
if(flag) continue;
}
if(flag) continue;
dp[i] = max(dp[j]+1, dp[i]);
}
ans = max(ans, dp[i]);
}
printf("%d\n", ans);
return 0;
}

E. 给你n(1e5)个节点的有根数(1 is root) ,每个点有一个值,1e5个操作,第一种操作,求从根1到给定点v的路径上的满足gcd(val[v], val[xi]),xi是路径上的点,输出xi,如果有多个输出距离v最近的一个, 没有输出-1 .第二种操作是把某点的权值更改为一个新值.

第二种操作不会超过50.

CF测评机本来跑的就很快而且给了10s,直接裸着搞。

先遍历有根树,记录每个点的父亲,之后对于每个询问直接往上找就可以了。还有其他优美的解法?

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define INF 1000000000
//typedef __int64 LL;
#define N 100010
int hh
, tot, n, q, val
, par
;
struct node {
int u, v, next;
}edge[700000];
void init() {
memset(hh, -1, sizeof(hh));
tot = 0;
}
void add(int u, int v) {
edge[tot].v = v; edge[tot].next = hh[u];
hh[u] = tot ++;
}
int gcd(int x, int y) {
if(!y) return x ;
return gcd(y, x%y);
}
void dfs(int u, int last) {
for(int i = hh[u]; i != -1; i = edge[i].next) {
int v = edge[i].v;
if(v == last) continue;
par[v] = u;
dfs(v, u);
}
}
void sol(int u) {
int tmp = par[u];
int vv = val[u];
while(tmp != 0) {
if(gcd(val[tmp], vv) != 1) {
printf("%d\n", tmp); return ;
}
tmp = par[tmp];
}
puts("-1");
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%d%d", &n, &q);
for(int i = 1; i <= n ;i++) scanf("%d", &val[i]);
init();
int u, v;
for(int i = 1; i < n; i++) {
scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
dfs(1, -1);
while(q-- ) {
int x, y, z;
scanf("%d%d", &x, &y);
if(x == 1) {
sol(y);
}
else {
scanf("%d", &z);
val[y] = z;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: