Codechef Bytecode 1-10

这个比赛好像不是很有名气,参加的人不多,前五题感觉比较平,题目有简单的也有中等的,但应该说不难,反正我是AK了。第3,4题还是很好的。

链接:http://www.codechef.com/BTCD2013/

1:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iomanip>
#include<cctype>
#include<string>
#include<memory>
#include<map>
#include<sstream>
#define mem(a) memset(a, 0, sizeof(a))
#define For(i, n) for(int i = 0; i < (n); ++i)
#define sl(a) strlen(a)
typedef long long LL;
typedef double dou;
const int Mod = 1000000007;
const double eps = 1e-8;
const LL inf = 1e18;
const int inf1 = 1e9;
const int N = 100005;
using namespace std;
 
int a[N], l[N], r[N], dp[N][20];
 
int main()
{
		LL n, m, t, i, j, k;
 
		cin >> t;
		while (t--)
		{
				cin >> n >> m;
				cout << n * m - n - m << endl;			
		}
		return 0;
}
是一个数论结论,(a, b) = 1, a, b > 0 时ax + by (x, y >= 0) 不能表示的最大的整数是a * b - a - b.

证明: a 或 b 是1的情况是显然的,下设a > 1, b > 1.

首先a * b - a - b不能被表示。反证,设a * b - a - b = a * m + b * n 则 a * b = (m + 1)*a + (n + 1) * b.右边系数全部大于1。注意到左边是a的倍数,所以a |(n + 1)*b, 因为(a, b) = 1, 所以a | (n + 1), 所以(n + 1) * b > a * b, 矛盾。
再证a * b - a - b + i (i > 0) 能被表示。因为a,b互质,最大公约数就是1,根据辗转相减的方法知m*a+n*b=1,不妨假设m>0,n<0,于是a*b-a-b+i=a*b-a-b+i*(m*a+n*b)。因为m>1(m=0意味着n*b=1不可能的),所以a*b-a-b+i*(m*a+*b)=(i*m-1)a+(a+i*n-1)*b,i*m-1>0,现在只要证明a+i*n-1>=0,因为i*m*a+i*n*b=i,如果,|i*n|>j*a其中j>0,那么i*m*a=i+|i*n|*b>j*a*b,所以i*m>j*b,所以i*m*a+i*n*b=(i*m-j*b)a-(|i*n|-j*a)*b=i,说明|i*n|>j*a时,我们就能调整i*m,i*n使得|i*n|<a,因此|i*n|<=a-1, 所以a+i*n-1>=0于是得证。

2:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iomanip>
#include<cctype>
#include<string>
#include<memory>
#include<map>
#include<sstream>
#define mem(a) memset(a, 0, sizeof(a))
#define For(i, n) for(int i = 0; i < (n); ++i)
#define sl(a) strlen(a)
typedef long long LL;
typedef double dou;
const int Mod = 1000000007;
const double eps = 1e-8;
const LL inf = 1e18;
const int inf1 = 1e9;
const int N = 100005;
using namespace std;
 
struct po
{
		list<int>s;
}p[20005];
 
int f[20005], vis[20005];
 
void dfs(int e, int s)
{
		vis[e] = 1;
		f[e] = s;
		list<int> :: iterator it = p[e].s.begin();
		while (it != p[e].s.end())
		{
				if (vis[*it] == 0)
						dfs(*it, e);
				it++;
		}
}
 
int main()
{
		LL n, m, t, i, j, k, x, y;
 
		cin >> t;
		while (t--)
		{
				cin >> n >> x >> y;
				for (i = 1; i <= n; ++i)
				{
						if (i != x)
						{
								cin >> m;
								p[i].s.push_back(m);
								p[m].s.push_back(i);
						}
				}
				dfs(y, y);
				for (i = 1; i <= n; ++i)
				{
						if (i != y)
								cout << f[i] << ' ';
				}
				cout << endl;
				for (i = 1; i <= n; ++i) p[i].s.clear();
				mem(vis);
		}
		return 0;
}

比较水的DFS.不多说。

5:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iomanip>
#include<cctype>
#include<string>
#include<memory>
#include<map>
#include<sstream>
#define mem(a) memset(a, 0, sizeof(a))
#define For(i, n) for(int i = 0; i < (n); ++i)
#define sl(a) strlen(a)
typedef long long LL;
typedef double dou;
const int Mod = 1000000007;
const double eps = 1e-8;
const LL inf = 1e18;
const int inf1 = 1e9;
const int N = 100005;
using namespace std;
 
int num[200], vis[40], f[200], vv[200];
 
int main()
{
		LL n, m, t, i, j, k, len, cnt, re;
		char s[100];
 
		cin >> t;
		while (t--)
		{
				mem(num), mem(s), mem(vis), mem(f), mem(vv);
				cin >> s;
				len = sl(s);
				cnt = re = 0;
				for (i = 0; i < len; ++i) num[s[i]]++;
				for (i = 0; i < 200; ++i) if (num[i]) cnt++;
				if (cnt == 1)
				{
						cout << (1 << len) - 1 << endl;
				}
				else
				{
				f[s[0]] = 1, vis[1] = re = 1, vv[s[0]] = 1;
				for (i = 1; i < len; ++i) 
				{
						if (vv[s[i]]) re = re * cnt + f[s[i]];
						else
						{
								for (j = 0; j < 40 && vis[j]; ++j);
								vis[j] = 1, f[s[i]] = j, vv[s[i]] = 1;
								re = re * cnt + j;
						}
				}
				cout << re << endl;		
				}
		}
		return 0;
}

(题意就是任给一串字符,你可以认为它是任何进制的数,但求它在十进制下的最小可能值)注意下进制数不能是1就可以了(wa了两次),首位也不能为0。

3和4是两道我觉得比较好的题。

思路都是DP, 其实3只能算递推,并没有涉及到动态保存能带来的好处,其实就是先算好了答案,放在数组里而已。代码中后有着重的地方是关键。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<deque>
#include<set>
#include<vector>
#include<iomanip>
#include<cctype>
#include<string>
#include<memory>
#include<map>
#include<sstream>
#pragma warning (disable : 4996)
#define mem(a) memset(a, 0, sizeof(a))
#define For(i, n) for(int i = 0; i < (n); ++i)
#define sl(a) strlen(a)
typedef long long LL;
typedef double dou;
const int Mod = 1000000007;
const double eps = 1e-8;
const LL inf = 1e18;
const int inf1 = 1e9;
const int N = 100005;
using namespace std;
#define M 12
LL dp[10][10][600];
LL ans[10][600];
 
int main ()
{
		LL i, j, k, n, m, t, re;
 
		for (i = 1; i < 10; ++i) //最大可取数字为i,首位为j,长度为k
				 dp[i][i][i + 1] = dp[i][0][i + 1] = 1;
		for (i = 1; i < 10; ++i)
				for (k = i + 2; k < 510; ++k) //*****//
						for (j = 0; j <= i; ++j)
						{
								if (j == 0) dp[i][0][k] = (dp[i][1][k - 1] + dp[i - 1][0][k - 1]) % Mod; //******************//
								else if (j == i) dp[i][i][k] = (dp[i][i - 1][k - 1] + dp[i - 1][i - 1][k - 1]) % Mod;
								else dp[i][j][k] = (dp[i][j - 1][k - 1] + dp[i][j + 1][k - 1]) % Mod;   //******************//
						}
		for (i = 1; i < 10; ++i)	
				for (k = i + 1; k < 510; ++k) //****//
						for (j = 1, ans[i][k] = ans[i][k - 1]; j <= i; ++j) //*****//
							ans[i][k] = (ans[i][k] + dp[i][j][k]) % Mod;
		cin >> t;
		while (t--)
		{
				scanf("%lld%lld", &n, &m);
				if (n > m) printf("0\n");
				else printf("%lld\n", ans[n - 1][m]);
		}
		
		return 0;
} 

4:

首先考虑一个两段开的区间(i , j), dp[i][j]表示从a[i]到a[j]的所有可能方案的代价最小值。设两个哨兵0, n+1.枚举i, j 之间所有第一步可取的方案,划归为子问题。取最小即可。最后写出来的代码倒是很简洁。(一开始贪心,猜的策略。。。wa了好多次)。复杂度是Z*Z*Z,10^6可以接受。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<stack>
#include<deque>
#include<list>
#include<set>
#include<vector>
#include<iomanip>
#include<cctype>
#include<string>
#include<memory>
#include<map>
#include<sstream>
#define mem(a) memset(a, 0, sizeof(a))
#define For(i, n) for(int i = 0; i < (n); ++i)
#define sl(a) strlen(a)
typedef long long LL;
typedef double dou;
const int Mod = 1000000007;
const double eps = 1e-8;
const LL inf = 1e18;
const int inf1 = 1e9;
const int N = 100005;
using namespace std;
 
int a[105], dp[105][105];
 
int main()
{
		int  n, m, re, t, i, j, k;
 
		cin >> t;
		while (t--)
		{
				cin >> m >> n;
				mem(dp);
				for (i = 1; i <= n; ++i) cin >> a[i];
				a[n + 1] = m + 1;	
				for (i = 2; i <= n + 1; ++i) 
						for (j = 0; j + i <= n + 1; ++j)
						{
								for (k = j + 1; k < i + j; ++k)
								{
										if (k == j + 1) dp[j][i + j] = (a[i + j] - a[j] - 2 + dp[j][k] + dp[k][i + j]);
										else dp[j][i + j] =  dp[j][i + j] > (a[i + j] - a[j] - 2 + dp[j][k] + dp[k][i + j]) ?  (a[i + j] - a[j] - 2 + dp[j][k] + dp[k][i + j]) : dp[j][i + j];
								}
						}
			cout << dp[0][n + 1] << endl;
		}
		return 0;
}

希望22号,另五道不要忽然变得特别难,能拿个好的名次.^_^

接着写。。。。无力吐槽数据。。。

6:

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<set>
#include<iostream>
#define LL long long
using namespace std;
 
 set<int> p;
 
bool witness(LL a,LL n)
{
    LL t,d,x;
    d=1;
    int i=ceil(log(n-1.0)/log(2.0)) - 1;
    for(;i>=0;i--)
    {
        x=d;  d=(d*d)%n;
        if(d==1 && x!=1 && x!=n-1) return true;
        if( ((n-1) & (1<<i)) > 0)
            d=(d*a)%n;
    }
    return d==1 ? false : true;
}
 
bool miller_rabin(LL n)
{
    int s[]={2,7,61};
    if(n==2)    return true;
    if(n==1 || ((n&1)==0))    return false;
    for(int i=0;i<3;i++)
        if(witness(s[i], n))    return false;
    return true;
}
 
int main()
{
    int n,cnt, x, y, i, j, t, en;
	cin >> t;             
    while(t--)
    {
				cin >> x >> y;
				cnt=0;
				for (i = 1; i * i < y / 2; ++i)
				{
						en = (int) sqrt(y - i * i + 0.5);
						for (j = i + 1; j <= en; j += 2)
								if (i * i + j * j >= x)
										if (miller_rabin(i * i + j * j)) 
										{
												if (!p.count(i * i + j * j))
												{
														cnt++;
														p.insert(i * i + j * j);
												}
										}
				}
				if (x <= 2 && y >= 2) cnt++;
			   cout << cnt << endl;
			   p.clear();
    }
    return 0;
} 

7:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mem(a) memset(a, 0, sizeof(a))
#define N 100005
#define M 1000005
#define LL long long
#pragma warning (disable : 4996)
using namespace std;
 
struct po
{
		int x, l, cnt, id;
		bool operator < (const po &t) const
		{
				return x < t.x;
		}
}p[N];
 
bool cmp(po a, po b)
{
		return a.id < b.id;
}
 
int main()
{
		int n, i, j, k, t, q, min, sum;
		cin >> t;
		while (t--)
		{
				mem(p);
				cin >> n;
				for (i = 0; i < n; ++i) scanf("%d%d", &(p[i].x), &(p[i].l)), p[i].cnt = 0, p[i].id = i;
				sort(p, p + n);
				for (i = n - 1; i >= 0; --i) 
				{
						p[i].cnt = 1, p[i].l += p[i].x - 1;
						for (j = i + 1; p[j].x <= p[i].l && j < n; ++j) p[i].cnt++, p[i].l = max(p[i].l, p[j].l);
				}
				sort(p, p + n, cmp);
				for (i = 0; i < n; ++i) printf("%d ", p[i].cnt);
				cout << endl;
		}
		return 0;
}
8:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mem(a) memset(a, 0, sizeof(a))
#define N 1000005
#define LL long long
#pragma warning (disable : 4996)
using namespace std;
 
int ql, qr, a[N], b[N], num[N], kill;
 
struct no
{
		int cnt, l, r;
}n[4*N];
 
void bld(int x, int l, int r)
{
		int m = (l + r) >> 1;
		n[x].cnt = 0;
		n[x].l = l;
		n[x].r = r;
 		if (r == l) return ;
		else bld(2* x, l, m), bld(2 * x + 1, m + 1, r);
 }
 
void maint(int x, int l, int r)
{
		int ls = x * 2, rs = 2 * x + 1, m = (l + r) >> 1;
		if (l < r)
		{
				n[ls].cnt += n[x].cnt, n[rs].cnt += n[x].cnt;
				maint(ls, l, m), maint(rs, m + 1, r);
		}
		else num[kill++] = n[x].cnt;
}
 
void upd(int x, int l, int r)
{
		int m = (l + r) >> 1, ls = 2 * x, rs = 2 * x + 1;
		if (l == r) n[x].cnt++;
		else
		{
				if (ql <= l&& qr >= r)  n[x].cnt++;
				else 
				{
						if (ql <= m) upd(ls, l, m);
						if(qr > m) upd(rs, m + 1, r);
				}
		}
}
 
 
int main()
{
		int nn, i, j, k, t, q;
		LL re;
		while (cin >> t)
		{
				mem(n), mem(num), kill = 0;
				cin >> nn >> q;
				for (i = 0; i < nn; ++i) cin >> a[i];
				sort(a, a + nn);
				bld(1, 1, nn);
				for (i = 0; i < q; ++i) 
				{
						cin >> ql >> qr;
						upd(1, 1, nn);
				}
				maint(1, 1, nn);
				sort(num, num + nn);
				for (i = 0, re = 0; i < nn; ++i)
						re += a[i] * num[i];
				cout << re << endl;
		}
		return 0;
}
9:

#include<iostream>
#include<cstring>
#include<set>
#include<cstdio>
#pragma warning (disable : 4996)
using namespace std;
#define N 100005
 
struct po
{
		int x, y;
		bool operator < (const po &t) const
		{
				if (x != t.x) return x < t.x;
				else return y < t.y;
		}
}p[N];
 
set<po> a;
 
int main()
{
		int n, i, j, k, x, y;
		char s[10] = {0};
		po tem;
		set<po>:: iterator iter;
		cin >> n;
		while (n--)
		{
				scanf("%s%d%d", s, &(tem.x), &(tem.y));
				if (s[0] == 'a')
				{
						if (!a.count(tem)) a.insert(tem);
				}
				else if (s[0] == 'e') a.erase(tem);
				else 
				{
						if (a.count(tem))
						{
								iter = a.find(tem);
								iter++;
								if (iter == a.end()) printf("-1\n");
								else printf("%d %d\n", (*iter).x, (*iter).y);
						}
						else
						{
								a.insert(tem);
								iter = a.find(tem);
								iter++;
								if (iter == a.end()) printf("-1\n");
								else printf("%d %d\n", (*iter).x, (*iter).y);
								a.erase(tem);
						}		
				}
		}
		return 0;
}

10:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mem(a) memset(a, 0, sizeof(a))
#define N 100005
#define M 1000005
#define LL long long
#pragma warning (disable : 4996)
using namespace std;
int a[N];
 
int main()
{
		int n, i, j, k, t, q, min, sum;
		LL re;
		cin >> t;
		while (t--)
		{
				cin >> n;
				for (i = 0, min = M, re = sum = 0; i < n; ++i) scanf("%d", a + i), min = min > a[i] ? a[i] : min, re ^= a[i], sum += a[i];
				if (re == 0)
						cout << sum - min << endl;
				else cout << "NO\n";
		}
		return 0;
}

水到不能再水。。。。Orz






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值