Codeforces Round #346 (Div. 2)

开黑被Skip...白打了一场= =,rating没升也没降。。。(论开黑的正确姿势)

A题:

题目描述:

求一个人在一个节点数为n的环上,从a位置走b步会到哪个位置。

题解:

水题,直接模就好了。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
	#define setfile() 
#else
	#define debug(...)
	#define filename ""
	#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif

#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
#define For(_i, _a, _b) for (R int (_i) = (_a); (_i) <= (_b); ++(_i))
#define Rep(_i, _a, _b) for (R int (_i) = (_b); (_i) >= (_a); ++(_i))
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
	R char ch; R int cnt = 0; R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ? minus = 1 : cnt = ch - '0';
	while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus ? -cnt : cnt;
}

int main()
{
//	setfile();
	R int n = FastIn(), a = FastIn(), b = FastIn();
	R int ans = a + b;
	while (ans < 0) ans += n;
	while (ans > n) ans -= n;
	printf("%d\n",ans == 0 ? n : ans );
	return 0;
}


B题:

题目描述:

给定n个人和m个队伍,每个人有一个名字,所属队伍和能力值。求每个队伍能力值前两名的名字。如果前两名不只两个人则输出“?”

题解:

按队伍为第一关键字,能力值为第二关键字排序。然后搞一搞就好了。当时考场上想复杂了,分类讨论了半天,推掉了重写了好几遍。悲催!

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
	#define setfile() 
#else
	#define debug(...)
	#define filename ""
	#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif

#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
	R char ch; R int cnt = 0; R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ? minus = 1 : cnt = ch - '0';
	while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus ? -cnt : cnt;
}
#define maxn 100010
struct people
{
	char name[50];
	int pos, v;
	inline bool operator < (const people &that)const{return pos < that.pos || (pos == that.pos && v > that.v);}
}p[maxn], f[maxn], s[maxn];
bool err[maxn];
int main()
{
//	setfile();
	R int n, m;
	scanf("%d %d\n", &n, &m);
	for (R int i = 1; i <= n; ++i)
	{
		scanf("%s %d %d\n", p[i].name, &p[i].pos, &p[i].v);
	}
	std::sort(p + 1, p + n + 1);
	for (R int i = 1; i <= n; ++i)
	{
		if (err[p[i].pos]) continue;
		err[p[i].pos] = 1;
		if (p[i].pos == p[i + 2].pos && (p[i].v == p[i + 2].v || p[i + 1].v == p[i + 2].v))
			puts("?");
		else
		{
			printf("%s %s\n",p[i].name, p[i + 1].name );
		}
	}
	return 0;
}



C题:

题目描述:

假装你已经有了n个玩具和m块钱。每一个玩具代表了一个数字,求你用m块钱最多能买多少你没有的玩具,输出方案。


题解:

贪心。从最小的开始买。买到不能买为止。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
	#define setfile() 
#else
	#define debug(...)
	#define filename ""
	#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif

#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
#define For(_i, _a, _b) for (R int (_i) = (_a); (_i) <= (_b); ++(_i))
#define Rep(_i, _a, _b) for (R int (_i) = (_b); (_i) >= (_a); ++(_i))
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
	R char ch; R int cnt = 0; R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ? minus = 1 : cnt = ch - '0';
	while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus ? -cnt : cnt;
}
#define maxn 100010
int a[maxn], ans[maxn];
int main()
{
//	setfile();
	R int n = FastIn(), m = FastIn(), maxx = 0, pos = 1, tot = 0;
	for (R int i = 1; i <= n; ++i)
		a[i] = FastIn(), cmax(maxx, a[i]);
	std::sort(a + 1, a + n + 1);
	for (R int i = 1; m > 0; ++i)
	{
//		printf("%d %d\n",i, m );
		if (pos <= n && a[pos] == i) {pos ++;continue;}
		m -= i;
		ans[++tot] = i;
	}
	printf("%d\n",m == 0? tot : tot -1 );
	for (R int i = 1; i <= tot-1 ; ++i)
		printf("%d ",ans[i] );
	m == 0 ?printf("%d",ans[tot] ) : 0;
	return 0;
}


D题:

题目描述:

在二维平面上给你n+1个点,然后这些点形成了一个回路,保证每条边与坐标轴平行。求有多少个线段所在直线穿过原封闭图形。


题解:

考场上又是写凸包又是写复杂的分类讨论的,结果比赛结束了才知道是找规律,并且结论是可以证明的。。。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
#else
	#define debug(...)
#endif

#define R register
#define getc() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
#define gmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define gmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1<<15],*S=B,*T=B;
inline int FastIn()
{
	R char ch;R int cnt=0;R bool minus=0;
	while (ch=getc(),(ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ?minus=1:cnt=ch-'0';
	while (ch=getc(),ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus?-cnt:cnt;
}
int n;
int main()
{
	n=FastIn();
	printf("%d\n",(n >> 1) - 2 );
	return 0;
}


E题:

题目描述:

给定n个点和m条无向边,求不包含链的联通块的个数。

题解:

dfs。没啦!

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
	#define setfile() 
#else
	#define debug(...)
	#define filename ""
	#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif

#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
	R char ch; R int cnt = 0; R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ? minus = 1 : cnt = ch - '0';
	while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus ? -cnt : cnt;
}
#define maxn 100010
int last[maxn], ecnt, next[maxn << 1], to[maxn << 1], fa[maxn], ans;
bool vis[maxn], find;
#define add(_a, _b) (to[++ecnt] = (_b), next[ecnt] = last[_a], last[_a] = ecnt)
void dfs(R int x)
{
	vis[x] = 1;
	for (R int i = last[x]; i; i = next[i])
	{
		if (vis[to[i]] && fa[x] != to[i] && !find) {ans--;find = 1 ;break;}
		else if (!vis[to[i]])
		{
			fa[to[i]] = x;
			dfs(to[i]);
		}
	}
}
int main()
{
//	setfile();
	R int n = FastIn(), m = FastIn();
	for (R int i = 1; i <= m; ++i)
	{
		R int a = FastIn(), b = FastIn();
		add(a, b);add(b, a);
	}
	for (R int i = 1; i <= n; ++i)
		if (!vis[i]) find = 0, dfs(i), ans++;
	printf("%d\n",ans);
	return 0;
}


F题:

题目描述:

给你一个N*M的矩阵,以及一个数K,你可以把矩阵里的数减少,使得剩下一个权值全部为某个数的四联通块(其他数都为0),且矩阵内所有数的和必须为K,且这个联通块里必须有一个数没有修改,修改只支持减法。

题解:

这题的限制条件有点多。做法就是先把权值排序,然后一个一个判断,用并查集维护已经出现过的数的联通块,如果某个数能被K整除且所在的已经出现的联通块的大小大于K/V,则输出答案。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
	#define setfile() 
#else
	#define debug(...)
	#define filename ""
	#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif

#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
	R char ch; R int cnt = 0; R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ? minus = 1 : cnt = ch - '0';
	while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus ? -cnt : cnt;
}
inline long long FastIn2()
{
	R char ch; R long long cnt = 0; R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ? minus = 1 : cnt = ch - '0';
	while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus ? -cnt : cnt;
}
#define maxn 2000010
struct poi
{
	int x, y, v;
	inline bool operator < (const poi &that) const {return v > that.v;}
}buff[maxn];
bool vis[maxn];
int Fa[maxn], size[maxn], ans[1010][1010];
#define pos(_i , _j) (((_i) - 1) * m + (_j))
int Find(R int x) {return Fa[x] == x ? x : Fa[x] = Find(Fa[x]);}
const int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
std::queue<int> q;
int main()
{
//	setfile();
	R int n = FastIn(), m = FastIn();R long long k = FastIn2(), cnt = 0;
	for (R int i = 1; i <= n; ++i)
		for (R int j = 1; j <= m; ++j)
		{
			buff[++cnt] = (poi){i, j, FastIn()};
		}
	std::sort(buff + 1, buff + cnt + 1);
	for (R int i = 1; i <= cnt; ++i)
	{
		Fa[i] = i;
		size[i] = 1;
	}
	for (R int i = 1; i <= cnt; ++i)
	{
		R int xx = buff[i].x, yy = buff[i].y, vv = buff[i].v;
		vis[pos(xx, yy)] = 1;
		R int f, f0 = Find(pos(xx, yy));
		for (R int j = 0; j < 4; ++j)
		{
			R int nx = xx + dx[j], ny = yy + dy[j];
			if (nx > 0 && nx <= n && ny > 0 && ny <= m && vis[pos(xx + dx[j], yy + dy[j])])
			{
				f = Find(pos(nx, ny));
				if (f != f0)
				{
					Fa[f] = f0;
					size[f0] += size[f];
				}
			}
		}
		if (k % vv != 0) continue;
		if (size[f0] < k / vv) continue;
		puts("YES");
		q.push(pos(xx, yy));
		R int cnt = k / vv - 1, tmp = cnt;
		ans[xx][yy] = vv;
		vis[pos(xx, yy)] = 0;
		while (!q.empty() && cnt > 0)
		{
			R int now = q.front(); q.pop();
			R int nx, ny = now % m;
			!ny ? ny = m : 0;
			nx = (now - ny) / m + 1;
			for (R int j = 0; j < 4 && cnt > 0; ++j)
			{
				R int nex = nx + dx[j], ney = ny + dy[j];
				if (nex > 0 && nex <= n && ney > 0 && ney <= m && Find(pos(nex, ney)) == f0 && vis[pos(nex, ney)])
					ans[nex][ney] = vv, q.push(pos(nex, ney)), cnt--, vis[pos(nex, ney)] = 0;
			}
		}
		for (R int ii = 1; ii <= n; ++ii)
		{
			for (R int jj = 1; jj <= m; ++jj) printf("%d ",ans[ii][jj] );
			puts("");
		}
		return 0;
	}
	puts("NO");
	return 0;
}
/*
4 3 8
2 2 2
1 1 1
1 2 1
1 1 1
*/


G题:

题目描述:
你有n个高度为hi的方块,然后你可以从上面开始取走一个联通块,求取的方案数。

题解:

DP。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef CT
	#define debug(...) printf(__VA_ARGS__)
	#define setfile() 
#else
	#define debug(...)
	#define filename ""
	#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout);
#endif

#define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
char B[1 << 15], *S = B, *T = B;
inline int FastIn()
{
	R char ch; R int cnt = 0; R bool minus = 0;
	while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
	ch == '-' ? minus = 1 : cnt = ch - '0';
	while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
	return minus ? -cnt : cnt;
}
#define maxn 1000010
const int mod = 1e9 + 7;
int h[maxn], f[maxn];
int main()
{
//	setfile();
	R int n = FastIn();
	R long long ans = 0;
	for (R int i = 1; i <= n; ++i) h[i] = FastIn() - 1;
	for (R int i = 1; i <= n; ++i)
	{
		ans += h[i];
		R int a = dmin(h[i - 1], h[i]);
		R int b = dmin(a, h[i + 1]);
		R int c = dmin(h[i], h[i + 1]);
		ans = (1ll * f[i - 1] * a + ans) % mod;
		f[i] = (1ll * f[i - 1] * b + c) % mod;
	}
	printf("%lld\n",ans );
	return 0;
}




 

posted @ 2016-03-31 19:44  cot  阅读(168)  评论(0编辑  收藏  举报