问题 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;
}