前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2016天梯模拟赛 进阶题解

2016天梯模拟赛 进阶题解

作者头像
ShenduCC
发布2018-04-26 17:30:39
7870
发布2018-04-26 17:30:39
举报
文章被收录于专栏:算法修养算法修养

L2-005 集合相似度

题目链接:

https://www.patest.cn/contests/gplt/L2-005

题目的意思是要求两个集合的交集中互不相同元素的个数和两个集合并集中互不相同的元素的个数

先求交集中互不相同的元素,然后用两个集合互不相同元素个数的和减去,就是并集中的个数

代码语言:javascript
复制
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <map>
#include <string>

using namespace std;
int n;
int a[55][1005];
int b[55];
double ans[55][55];
int Get[55];
int k;
int x,y;
int bin(int x,int y)
{
	int l=0;
	int r=b[y]-1;
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(a[y][mid]==x)
			return 1;
		else if(x>a[y][mid])
			l=mid+1;
		else
			r=mid-1;
	}
	return 0;
}
int fun(int x,int y)
{
	int num=0;
	int i=0,j=0;
	for(int i=0;i<b[x];i++)
	{
		if(i==0||a[x][i]!=a[x][i-1])
			num+=bin(a[x][i],y);
	}
	return num;
}
int get(int x)
{
	int num=0;
	for(int i=1;i<b[x];i++)
	{
		if(a[x][i]!=a[x][i-1])
			num++;
	}
	num++;
	return num;
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&b[i]);
			for(int j=0;j<b[i];j++)
			{
				scanf("%d",&a[i][j]);
			}
			sort(a[i],a[i]+b[i]);
		}
		for(int i=1;i<=n;i++)
			Get[i]=get(i);
		for(int i=1;i<=n;i++)
		{
			for(int j=i;j<=n;j++)
			{
				if(i==j)
					ans[i][j]=1;
				else
				{
					int num1=fun(i,j);
					int num2=Get[i]+Get[j];
					int num3=num2-num1;
					ans[i][j]=1.0*num1/num3;
				}

			}
		}
		scanf("%d",&k);
		for(int i=1;i<=k;i++)
		{
			scanf("%d%d",&x,&y);
			if(x>y)
				swap(x,y);
			printf("%.2f%%\n",100.0*ans[x][y]);
		}
	}
}

L2-006 树的遍历

题目链接:

https://www.patest.cn/contests/gplt/L2-006

根据二叉树的后序中序建立这颗二叉树,二叉树可以用链式指针存储也可以用数组存储

代码语言:javascript
复制
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <queue>

using namespace std;
typedef struct Tree
{
	int data;
	Tree *lchild;
	Tree *rchild;
}a[40];
int post[40];
int in[40];
int n;
int ans[40];
void dfs(int l1,int r1,int l2,int r2,Tree* &root)
{
	root=new Tree();
	int i;
	for( i=l1;i<=r1;i++)
		if(in[i]==post[r2])
			break;
	root->data=post[r2];
	if(i==l1)
		root->lchild=NULL;
	else
		dfs(l1,i-1,l2,l2+i-l1-1,root->lchild);
	if(i==r1)
		root->rchild=NULL;
	else
		dfs(i+1,r1,r2-(r1-i),r2-1,root->rchild);
}
int cnt;
void bfs(Tree *tree)
{
	queue<Tree*> q;
	q.push(tree);
	while(!q.empty())
	{
		Tree *root=q.front();
		q.pop();
		ans[cnt++]=root->data;
		if(root->lchild!=NULL)
			q.push(root->lchild);
		if(root->rchild!=NULL)
			q.push(root->rchild);
	}
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		for(int i=1;i<=n;i++)
			scanf("%d",&post[i]);
		for(int i=1;i<=n;i++)
			scanf("%d",&in[i]);
		Tree *tree;
		dfs(1,n,1,n,tree);
		cnt=0;
		bfs(tree);
		for(int i=0;i<cnt;i++)
		{
			if(i==cnt-1)
				printf("%d\n",ans[i]);
			else
				printf("%d ",ans[i]);
		}
	}
	return 0;
}

L2-007 家庭房产

https://www.patest.cn/contests/gplt/L2-007

按照编号和编号之间的关系,建立一个图,然后dfs求连通块

代码语言:javascript
复制
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <string>
#include <vector>

using namespace std;
struct Node
{
	int next;
	int value;
	int weight;
}edge[100005*4];
int head[10005];
int flag[10005];
int vis[10005];
int tot;
int n;
int tag[1005];
void add(int x,int y,int z)
{
	edge[tot].weight=z;
	edge[tot].value=x;
	edge[tot].next=head[y];
	head[y]=tot++;
}
int area[1005];
int house[1005];
int member[15];
struct node
{
	int minn;
	int num;
	int house;
	int area;
	double ah;
	double aa;
}b[10005];
int cmp(node a,node b)
{
	if(a.aa==b.aa)
		return a.minn<b.minn;
	return a.aa>b.aa;
}
void dfs(int x,int cnt)
{
	vis[x]=1;
	for(int i=head[x];i!=-1;i=edge[i].next)
	{
		int y=edge[i].value;
		if(!tag[edge[i].weight])
		{
			b[cnt].area+=area[edge[i].weight];
			b[cnt].house+=house[edge[i].weight];
			tag[edge[i].weight]=1;
		}
		if(vis[y])
			continue;
		b[cnt].minn=min(b[cnt].minn,y);
		b[cnt].num++;
		dfs(y,cnt);
	}
}
int k;
int main()
{
	scanf("%d",&n);
	memset(head,-1,sizeof(head));
	memset(flag,0,sizeof(flag));
	tot=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=3;j++)
		{scanf("%d",&member[j]);flag[member[j]]=1;}
		scanf("%d",&k);
		for(int j=4;j<=k+3;j++)
		{scanf("%d",&member[j]);flag[member[j]]=1;}
		scanf("%d%d",&house[i],&area[i]);
		for(int j=1;j<=k+3;j++)
		{
			for(int p=1;p<=k+3;p++)
			{
				if(member[j]!=-1&&member[p]!=-1)
				{
					add(member[j],member[p],i);
					add(member[p],member[j],i);
				}
			}
		}
	}
	int cnt=-1;
	memset(vis,0,sizeof(vis));
	memset(tag,0,sizeof(tag));
	for(int i=0;i<10000;i++)
	{
		if(!vis[i]&&flag[i])
		{
			b[++cnt].minn=i;
			b[cnt].num=1;b[cnt].house=0;b[cnt].area=0;
			dfs(i,cnt);
		}
	}
	for(int i=0;i<=cnt;i++)
	{
		b[i].aa=1.0*b[i].area/b[i].num;
		b[i].ah=1.0*b[i].house/b[i].num;
	}
	sort(b,b+cnt+1,cmp);
	printf("%d\n",cnt+1);
	for(int i=0;i<=cnt;i++)
	{
		printf("%04d %d %.3f %.3f\n",b[i].minn,b[i].num,b[i].ah,b[i].aa);
	}
	return 0;
}

L2-008 最长对称子串

https://www.patest.cn/contests/gplt/L2-008

暴力三个for循环,最近学了回文树,就用了

代码语言:javascript
复制
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
#include <stdio.h>
#include <map>
#include <string>

using namespace std;
#define MAX 1000
char str[MAX+5];
int ans;
struct Tree
{
	int next[MAX+5][500];
	int fail[MAX+5];
	int len[MAX+5];
	int s[MAX+5];
	int last;
	int p;
	int n;
	int new_node(int x)
	{
		memset(next[p],0,sizeof(next[p]));
		len[p]=x;
		return p++;
	}
	void init()
	{
		p=0;
		new_node(0);
		new_node(-1);
		last=0;
		n=0;
		s[0]=-1;
		fail[0]=1;
	}
	int get_fail(int x)
	{
		while(s[n-len[x]-1]!=s[n])
			x=fail[x];
		return x;
	}
	int add(int x)
	{
		s[++n]=x;
		int cur=get_fail(last);
		if(!(last=next[cur][x]))
		{
			int now=new_node(len[cur]+2);
			ans=max(ans,len[cur]+2);
			fail[now]=next[get_fail(fail[cur])][x];
			next[cur][x]=now;
			last=now;

		}
		return 1;
	}
}tree;
int main()
{
	gets(str);

	int len=strlen(str);
	tree.init();
	ans=0;
	for(int i=0;i<len;i++)
		tree.add(str[i]);
	printf("%d\n",ans);

	return 0;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-05-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档