2013 Phuket Regional

A Spanning trees in a secure lock pattern

用矩阵运算计算生成树数量,题目已经给出计算方式,只要按着算一遍...

有兴趣的可以去看看Matrix-Tree定理(Kirchhoff矩阵-树定理)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 41;
int fx[8][2]={
	{1,1},{1,-1},{-1,1},{-1,-1},
	{1,0},{0,-1},{-1,0},{0,1}};
long long Mat[N][N];
int n;
long long Gauss(int n){
	long long ans=1,t,sav;
	int i,j,k;
	for(int i=1;i<n;++i){
		for(j=i+1;j<n;++j){
			while(Mat[j][i]){
				t=Mat[i][i]/Mat[j][i];
				for(k=1;k<n;++k)
					Mat[i][k]-=t*Mat[j][k],swap(Mat[i][k],Mat[j][k]);
				ans=-ans;
			}
		}
		if(Mat[i][i]==0) return 0;
		ans=ans*Mat[i][i];
	}
	return ans;
}

int main()
{
	int T;scanf("%d",&T);
	while(T--){
		scanf("%d",&n);
		memset(Mat,0,sizeof Mat);
		int m=n*n;
		for(int i=0;i<m;++i){
			int num=0;
			int x=i/n,y=i%n;
			for(int j=0;j<8;++j){
				int tx=x+fx[j][0];
				int ty=y+fx[j][1];
				if(tx>=0 && tx<n && ty>=0 && ty<n){
					Mat[i][tx*n+ty]=-1;
					++num;
				}

			}
			Mat[i][i]=num;
		}
		long long ans=Gauss(m);
		printf("%lld\n",ans);
	}
	return 0;
}

B Teaching Hazard

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 100100
typedef long long ll;
using namespace std;

ll a[maxn],pri[maxn],prime=0;
ll top,ans,n,x,tmp;
bool b[maxn]={false};

void getpri()
{
	for (int i=2; i<maxn; i++)
	{
		if (b[i]) continue;
		pri[++prime]=i;
		for (int j=i+i; j<maxn; j+=i) b[j]=true;
	}
}

void init()
{
	ans=top=0;
	for (int i=1; i<=n; i++)
	{
		a[i]=0,tmp=n;
		while (tmp/pri[i]>0) a[i]+=(tmp=tmp/pri[i]);
		if (a[i]==0) 
		{
			top=i-1;
			return;
		}
	}
}

ll getnum(ll X)
{
	ll tot=1,cur;
	for (int i=1; i<=top && a[i]>=X; i++) tot*=a[i]/X+1;
	return tot;
}

int main()
{
	getpri();
	while (scanf("%lld%lld",&n,&x) && (n|x) )
	{
		init();
		ll pre,next=getnum(x);
		while (true)
		{
			x++;
			pre=getnum(x);
			ans+=(next-pre)*(next-pre-1)/2;
			if (pre==1) break;
			swap(pre,next);
		}
		printf("%lld\n",ans);
	}
	return 0;
}

C Counting Lattice Squares

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 1000010
typedef long long LL;
LL A[MAXN], B[MAXN], C[MAXN], a[MAXN];
int main() {
	memset(a, 0, sizeof(a));
	for(int i = 1; i <= 1000000; i += 2) {
		a[i] = i;
	}
	A[0] = B[0] = C[0] = 0;
	for(int i = 1; i <= 1000000; i ++) {
		A[i] = A[i - 1] + a[i];
		B[i] = B[i - 1] + a[i] * i;
		C[i] = C[i - 1] + a[i] * i * i;
	}

	int n, m;
	while(scanf("%d%d", &n, &m), n) {
		if(n > m) std::swap(n, m);
		LL ans = A[n] * (n + 1) * (m + 1) - B[n] * (n + 1 + m + 1) + C[n];
		printf("%lld\n", ans);
	}
	return 0;
}


D Seven Segment Display

该题题意学过数电的同学应该很快就能看懂...不过和数电没什么关系= =

就是给你一个图要你判断它是否能组成给出的结构,代码题

首先将0~9分类,0第一类,1、2、5、7第二类,8第三类,6、9第四类,3、4第五类

然后就是计算图的度,根据要求把图分割求链的长度,然后判断是否相等即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N = 510, M = 1010;
vector< pair<int,int> > ans;
struct Edge{
	int next,to;
} e[M*2];
int n,m,tot;
int head[N],de[N],dep[4],ret,res;
bool vis[N];

void add_edge(int a,int b){
	e[tot].to=b;e[tot].next=head[a];
	head[a]=tot++;
}

void dfs(int p){
	vis[p]=true;
	for(int i=head[p];~i;i=e[i].next)
		if(!vis[e[i].to]) dfs(e[i].to);
}

int dfs2(int p,int fa){
	if(p==ret) return 0;
	int res;
	for(int i=head[p];~i;i=e[i].next)
		if(e[i].to!=fa) res=dfs2(e[i].to,p)+1;
	return res;
}

int main()
{
	int T,cas=1,a,b;scanf("%d",&T);
	for(cas=1;cas<=T;++cas){
		printf("Case %d: ",cas);
		scanf("%d%d",&n,&m);tot=0;
		ans.clear();
		memset(head,-1,sizeof head);
		memset(de,0,sizeof de);
		memset(dep,0,sizeof dep);
		memset(vis,0,sizeof vis);
		for(int i=0;i<m;++i){
			scanf("%d%d",&a,&b);
			add_edge(a,b);
			add_edge(b,a);
			++de[a],++de[b];
		}
		bool ok=true;
		dfs(1);
		for(int i=1;i<=n;++i)
			if(!vis[i]) ok=false;
		for(int i=1;i<=n;++i){
			if(de[i]>3 || de[i]==0){
				ok=false;
				break;
			}
			++dep[de[i]];
		}
		if(dep[3]>2) ok=false;
		if(!ok){
			printf("0\n");
			if(cas!=T) printf("\n");
			continue;
		}
		if(dep[2]==n && n>=6){
			if((n-6) % 6 == 0) ans.push_back(make_pair(0,n/6-1));
		}
		else if(dep[1]==2 && dep[2]==n-2){
			if((n-3) % 2 == 0) ans.push_back(make_pair(1,(n-3)/2));
			if((n-6) % 5 == 0) ans.push_back(make_pair(2,(n-6)/5)),ans.push_back(make_pair(5,(n-6)/5));
			if((n-4) % 3 == 0) ans.push_back(make_pair(7,(n-4)/3));
		}
		else if(dep[3]==2 && dep[2]==n-2){
			if((n-6) % 7 == 0) ans.push_back(make_pair(8,(n-6)/7));
		}
		else if(dep[3]==1 && dep[1]==1 && dep[2]==n-2){
			for(int i=1;i<=n;++i){
				if(de[i]==1) res=i;
				if(de[i]==3) ret=i;
			}
			int l=dfs2(res,-1);
			int last=n-l-1;
			if(l % 2 == 0) l=(l-2)/2;
			if((last-3) % 4 == 0) last=(last-3)/4;
			if(l==last) ans.push_back(make_pair(6,l)),ans.push_back(make_pair(9,l));
		}
		else if(dep[3]==1 && dep[1]==3 && dep[2]==n-4){
			vector<int> ii,ll;
			for(int i=1;i<=n;++i){
				if(de[i]==3) ret=i;
				if(de[i]==1) ii.push_back(i);
			}
			for(int i=0;i<3;++i)
				ll.push_back(dfs2(ii[i],-1));
			sort(ll.begin(),ll.end());
			if(ll[2]==2*ll[0]){
				if(ll[0]==ll[1]) ans.push_back(make_pair(4,ll[0]-1));
				if(ll[1]==ll[2]) ans.push_back(make_pair(3,ll[0]-1));
			}
		}
		else ok=false;
		sort(ans.begin(),ans.end());
		printf("%d\n",ans.size());
		for(int i=0;i<ans.size();++i)
			printf("%d %d\n",ans[i].first,ans[i].second);
		if(cas!=T) printf("\n");
	}
	return 0;
}

E Airport Sort

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 20010
struct P {
	int tic, no, loc;
	bool operator < (const P &t) const {
		if(no != t.no) return no < t.no;
		return loc < t.loc;
	}
}p[MAXN];
int N, K;
void input() {
	int x;
	scanf("%d%d", &N, &K);
	for(int i = 1; i <= N; i ++) {
		scanf("%d", &x);
		p[i].tic = x, p[i].no = (x - 1) / K, p[i].loc = i;
	}
	std::sort(p + 1, p + 1 + N);
}

int sum[4 * MAXN], D;
void build() {
	for(D = 1; D < N + 2; D <<= 1);
	for(int i = 0; i < D; i ++) {
		if(i >= 1 && i <= N) sum[D + i] = 1;
		else sum[D + i] = 0;
	}
	for(int i = D - 1; i >= 1; i --) {
		sum[i] = sum[i << 1] + sum[i << 1 | 1];
	}
}
void update(int i) {
	for(i >>= 1; i > 0; i >>= 1) {
		sum[i] = sum[i << 1] + sum[i << 1 | 1];
	}
}
int query(int x, int y) {
	int ans = 0;
	for(int i = D + x - 1, j = D + y + 1; i + 1 != j; i >>= 1, j >>= 1) {
		if(~i & 1) ans += sum[i ^ 1];
		if(j & 1) ans += sum[j ^ 1];
	}
	return ans;
}
void process() {
	int X = 0, Y = 0;

	for(int i = 1; i <= N; i ++) {
		Y = std::max(Y, std::abs(p[i].loc - i));
	}

	build();
	for(int i = 1; i <= N; i ++) {
		if(p[i].loc > 1) X += query(1, p[i].loc - 1);

		sum[D + p[i].loc] = 0, update(D + p[i].loc);
	}

	printf("%d\n", X - Y);
}
int main() {
	//freopen("test.in", "rb", stdin);

	int t;
	scanf("%d", &t);
	for(int tt = 1; tt <= t; tt ++) {
		input();
		printf("Case %d: ", tt);
		process();
	}
	return 0;
}

F Boxes

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MOD 10007
typedef long long LL;
struct Box {
	int w, n;
	bool operator < (const Box &t) const {
		return w > t.w;
	}
}b[110];
int B;
int N, W;
int f[110][110][1010];
int fac[210], ni[210], facNi[210];
void input() {
	scanf("%d%d", &N, &W);
	B = 0;
	for(int i = 0; i < N; i ++) {
		int w;
		scanf("%d", &w);
		int id = -1;
		for(int j = 1; j <= B; j ++) {
			if(b[j].w == w) {
				id = j;
				break;
			}
		}
		if(id == -1) {
			++ B;
			b[B].w = w;
			b[B].n = 1;
		} else {
			++ b[id].n;
		}
	}
}
void prepare() {
	std::sort(b + 1, b + 1 + B);
	for(int i = 0; i <= B; i ++) {
		for(int j = 0; j <= N; j ++) {
			for(int k = 0; k <= W; k ++) {
				f[i][j][k] = -1;
			}
		}
	}
	f[0][0][0] = 1;
	for(int i = 1; i <= B; i ++) {
		for(int j = 0; j <= N; j ++) {
			for(int k = 0; k <= W; k ++) {
				bool ok = false;
				int ans = 0;
				if(f[i - 1][j][k] != -1) {
					ok = true;
					ans += f[i - 1][j][k];
				}

				for(int m = 1; m <= b[i].n; m ++) {
					int pj = j - m, pk = k - b[i].w * m;
					if(pj < 0 || pk < 0) break;
					if(f[i - 1][pj][pk] != -1) {
						ok = true;
						ans += ((LL)fac[pj + m] * facNi[m] * facNi[pj] * f[i - 1][pj][pk]) % MOD;
						if(ans >= MOD) ans -= MOD;
					}
				}

				if(ok) f[i][j][k] = ans;
				else f[i][j][k] = -1;
			}
		}
	}
}

int power(int A,int B)
{
	int tot=1;
	while (B)
	{
		if (B&1) tot=(tot*A)%MOD;
		A=(A*A)%MOD;
		B>>=1;
	}
	return tot;
}

void process() {
	int ans = 0;
	for(int r = 0; r < W; r ++) {
		int t = 1, n = 0, space = 0;

		int i = B;
		for(; i >= 1; i --) {
			if(b[i].w > r) break;

			t = ((LL)fac[n + b[i].n] * facNi[n] * facNi[b[i].n] * t) % MOD;

			space += b[i].n * b[i].w;
			n += b[i].n;
		}


		if(space <= W - r) {
			space = W - r - space;
			int sum = 0;
			for(int j = 0; j <= N; j ++) {
				if(f[i][j][space] != -1) {
					sum += ((LL)fac[n + j] * facNi[n] * facNi[j] * f[i][j][space]) % MOD;
					if(sum >= MOD) sum -= MOD;
				}
			}
			ans += (t * sum) % MOD;
			if(ans >= MOD) ans -= MOD;
		}
	}
	printf("%d\n", ans);
}

int main() {
	fac[0] = facNi[0] = 1;
	for(int i = 1; i <= 200; i ++) {
		int ni = power(i, MOD - 2);
		fac[i] = fac[i - 1] * i % MOD;
		facNi[i] = facNi[i - 1] * ni % MOD;
	}

	int t, tt;
	scanf("%d", &t);
	for(tt = 1; tt <= t; tt ++) {
		input();
		prepare();
		printf("Case %d: ", tt);
		process();
	}
	return 0;
}

G Meeting Room Arrangement

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

struct Node{
	int s,f;
} q[30];
int n,tot,ans;

bool cmp(Node a,Node b){
	return a.s==b.s ? a.f<b.f : a.s<b.s;
}

void dfs(int o,int res){
	ans=max(ans,res);
	for(int i=o+1;i<tot;++i)
		if(q[i].s>=q[o].f) dfs(i,res+1);
}

int main()
{
	//freopen("test.in","rb",stdin);
	scanf("%d",&n);
	while(n--){
		tot=0;
		while(scanf("%d%d",&q[tot].s,&q[tot].f),q[tot].s+q[tot].f) ++tot;
		sort(q,q+tot,cmp);++tot;
		ans=0;
		for(int i=0;i<tot;++i) dfs(i,1);
		printf("%d\n",ans);
	}
	return 0;
}

H


I Cabin Baggage

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,ans;

int main()
{
	//freopen("test.in","rb",stdin);
	scanf("%d",&n);
	while(n--){
		double l,w,d,we;
		scanf("%lf%lf%lf%lf",&l,&w,&d,&we);
		bool ok=true;

		if(l<=56.00 && w<=45.00 && d<=25.00) ok=true;
		else if(l+w+d <= 125.00) ok=true;
		else ok=false;
		if(we>7) ok=false;
		if(ok) puts("1"),++ans;
		else puts("0");
	}
	printf("%d\n",ans);
	return 0;
}

J Minimal Subarray Length

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 500010
typedef long long LL;
int N, a[MAXN], X;
int D, tree[4 * MAXN];
LL A[MAXN];
int M;
void build() {
	A[0] = 0;
	for(int i = 1; i <= N; i ++) {
		A[i] = a[i] + A[i - 1];
	}
	std::sort(A + 1, A + 1 + N);
	M = std::unique(A + 1, A + 1 + N) - (A + 1);
	for(D = 1; D < M + 2; D <<= 1);
	memset(tree, 0, sizeof(tree[0]) * 2 * D);
}
int findId(LL sum) {
	int min = 0, max = M + 1, mid;
	for(;;) {
		mid = (min + max) >> 1;
		if(mid == min) break;
		if(A[mid] <= sum) min = mid;
		else max = mid;
	}
	return mid;
}
void update(int i) {
	for(i >>= 1; i > 0; i >>= 1) {
		tree[i] = std::max(tree[i << 1], tree[i << 1 | 1]);
	}
}
int query(int x, int y) {
	int ans = 0;
	for(int i = D + x - 1, j = D + y + 1; i + 1 != j; i >>= 1, j >>= 1) {
		if(~i & 1) ans = std::max(ans, tree[i ^ 1]);
		if(j & 1) ans = std::max(ans, tree[j ^ 1]);
	}
	return ans;
}
void process() {
	int ans = N + 1;
	LL sum = 0;
	for(int i = 1; i <= N; i ++) {
		sum += a[i];
		if(a[i] >= X) ans = 1;
		if(sum >= X) ans = std::min(ans, i);

		LL x = sum - X;
		int id = findId(x);
		if(id > 0) {
			int j = query(1, id);
			if(j > 0 && i - j < ans) ans = i - j;
		}

		id = findId(sum);
		tree[D + id] = i, update(D + id);
	}

	printf("%d\n", ans <= N ? ans : -1);
}
int main() {
	//freopen("test.in", "rb", stdin);
	int t;
	scanf("%d", &t);
	while(t --) {
		scanf("%d%d", &N, &X);
		for(int i = 1; i <= N; i ++) {
			scanf("%d", &a[i]);
		}
		build();
		process();
	}
	return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值