中石油训练赛--第十二场

问题 A: Limited Insertion

snuke有一个空序列a。他将对这个序列执行n个操作。

在第 i 次运算中,他选择一个满足1≤j≤i 的整数 j,并在a中的位置 j 处插入j(起点是位置1)。

给你一个长度为n的序列b。确定a是否可能等于b。

N次操作后,如果是,显示一个可能的操作序列来实现它。

约束

·输入中的所有值都是整数。

·1≤N≤100

·1≤bi≤n

样例输入

3

1 2 1

样例输出

1

1

2

思路

教主教的。倒着想,最大的那个a[i]==i的数一定是最后放的,否则,它的位置将会改变。那么每次找到一个数后,删除它,把剩下的数当做1--n-1的数组,循环处理。因为n最大为100,所以暴力就可以。如果在寻找过程中找不到这样的数,那么数组a一定不能等于数组b。

代码

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f
const int N=110;
int a[N],b[N];
int main()
{
	int n,flag=1;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]);
	int m=n;
	for(int i=1;i<=n;i++)
	{
		int maxi=-inf,u=-1;
		for(int j=1;j<=m;j++)
		{
			if(b[j]==j&&b[j]>maxi)
			{
				maxi=b[j];
				u=j;
			}
		}
		if(u==-1)
		{
			flag=0;
			break;
		}
		for(int j=u;j<m;j++)
			b[j]=b[j+1];
		m--;
		a[i]=maxi;
	}
	if(!flag)
		printf("-1\n");
	else
	{
		for(int i=n;i>=1;i--)
			printf("%d\n",a[i]);
	}
	return 0;
}

问题 B: Balanced Neighbors

给你n个点,让你构建一个图,使得每个顶点有一个值,这个值是与它相连的每个顶点的下标和,每个顶点的值相等。

思路

如果n为奇数,例如5:1和4一组,2和3一组,同一组内的不连接,其他点连接。

如果n为偶数,例如6:1和6一组,2和5一组,3和4一组,同一组内的不连接,其他点连接。

n最大为100,暴力求就可以了。

代码

#include<iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int N=105;
bool vis[N][N];//标记 
int main()
{
	int n;
	scanf("%d",&n);
	memset(vis,0,sizeof(vis));
	if(n%2)
	{
		printf("%d\n",((n-1)*(n-2)+n-1)/2);
		for(int i=1;i<n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(i+j!=n&&i!=j&&!vis[min(i,j)][max(i,j)])
				{
					printf("%d %d\n",i,j);
					vis[min(i,j)][max(i,j)]=1;
				}
			}
		}
		for(int i=1;i<n;i++)
		{
			if(!vis[min(i,n)][max(i,n)])
				printf("%d %d\n",i,n);
		}
	}
	else
	{
		printf("%d\n",n*(n-2)/2);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				if(i+j!=n+1&&i!=j&&!vis[min(i,j)][max(i,j)])
				{
					printf("%d %d\n",i,j);
					vis[min(i,j)][max(i,j)]=1;
				}
			}
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值