A:水题,我的做法是算2×2格子的和,不为2即可
B:水题,贪心+二分查找
C:我是手写几个数的表,看的规律,很容易发现,前两个后两个可以分为一组,第一个是2,第二个是n,倒数第二个是1,倒数第一个是n-1...以此类推,注意可以用stl的next_permutation函数枚举,方便看规律。具体证明没推,cf貌似有。
上代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=100005;
int a[N];
int main()
{
int i,n;
scanf("%d",&n);
if(!(n%4==0) && !(n%4==1)) {printf("-1");return 0;}
if(n%4==0)
{
int h=2;
int t=n;
for(i=1;i<=n/2;++i)
{
if(i%2==1)
{
a[i]=h;
a[n-i]=h-1;
h=h+2;;
}
if(i%2==0)
{
a[i]=t;
a[n-i+2]=t-1;
t=t-2;
}
}
}
else if(n%4==1)
{
int h=2;
int t=n;
for(i=1;i<=n/2;++i)
{
if(i%2==1)
{
a[i]=h;
a[n-i]=h-1;
h=h+2;;
}
if(i%2==0)
{
a[i]=t;
a[n-i+2]=t-1;
t=t-2;
}
}
a[n/2+1]=(n+1)/2;
}
for(i=1;i<=n;++i)
printf("%d ",a[i]);
return 0;
}
D:其实不用想的太复杂,枚举即可。这里用到了deque双端队列,实现起来较为方便,每次把分组的最后一组的第一个加到队尾,然后每组第一个移到后面一组第一个位置处,然后将队头删除即可
#include<iostream>//deque
#include<algorithm>
#include<cstdio>
#include<deque>
using namespace std;
deque<int> d;
int main()
{
int i,n;
scanf("%d",&n);
for(i=1;i<=n;++i)
d.push_back(i);
for(i=2;i<=n;++i)
{
int l=(n-1)/i*i;
d.push_back(d[l]);
while(l)
{
d[l]=d[l-i];
l=l-i;
}
d.pop_front();
}
for(i=0;i<n;++i)
printf("%d ",d[i]);
return 0;
}
E:不错的题,类似于匹配括号,这里用到了栈,因为右面要是负数,显然从右往左扫比较方便。将需要匹配的位置加入栈中,依次匹配即可
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1000005;
int a[N],b[N],st[N];
int main()
{
int x;
int i,n,t;
scanf("%d",&n);
if(n%2==1) {printf("NO");return 0;}
for(i=1;i<=n;++i)
scanf("%d",&a[i]);
scanf("%d",&t);
for(i=1;i<=t;++i)
{
scanf("%d",&x);
b[x]=1;
}
int now=0;
for(i=n;i>=1;--i)
{
if(!b[i] && (now && a[i]==a[st[now]])) a[st[now--]]=-a[i];
else st[++now]=i;
}
//从右至左匹配,将右面变成负数
if(now==0)
{
printf("YES\n");
for(i=1;i<=n;++i)
printf("%d ",a[i]);
}
else printf("NO\n");
return 0;
}