Time Limit:1s Memory Limit:1024MByte
Submissions:541Solved:155
In a mysterious cave, PigVan ( Mr.Van's pet ) has lived for thousands years. PigVan absorbed the power of nature, and it may pretend a human in speaking, walking and so on.
One day, he bought some valuable stone, and divided them into n piles of stone where the ith pile (1≤i≤n) contains values ai .
After PigVan put them in a line, he wants to play a game.
In the boring game, he can do this operation:
Choose a stone pile ai (i>1)and its two adjacent piles ai-1, ai+1, turn (ai-1, ai, ai+1) to (ai-1 + ai, -ai, ai + ai+1).
PigVan wonders whether he can get (b1, b2, b3, …, bn) after several operations.
Note:
If you choose the last pile an, the operation will be ( an-1 + an, -an ) .
For each test case:
In the first line, there are only one integer nn(n≤10 5), indicating the number of food piles.
The second line is nn integers indicate sequence aa ( | a i | ≤ 10 6).
The third line is nn integers indicate sequence bb ( | b i | ≤ 10 6).
然后用广搜做了
下面代码
#include<stdio.h>
int s[1000005];
int i,j,k,l,n;
struct node
{
int a[1000];
} sz[100000];
int jh(int m)
{
for(int p=0;p<n;p++)
{
sz[l].a[p]=sz[k].a[p];
}
if(m==n-1)
{
sz[l].a[m-1]=sz[k].a[m]+sz[k].a[m-1];
sz[l].a[m]=-sz[k].a[m];
}
else
{
sz[l].a[m-1]=sz[k].a[m]+sz[k].a[m-1];
sz[l].a[m+1]=sz[k].a[m]+sz[k].a[m+1];
sz[l].a[m]=-sz[k].a[m];
}
l++;
}
int bfs()
{
for(k=0;; k++)
{
for(j=1; j<n; j++)
{
jh(j);
int flag1=0;
for(i=0; i<n; i++)
{
printf("%d ",sz[l-1].a[i]);
if(sz[l-1].a[i]!=s[i])
{
flag1=1;
}
}
printf("\n");
if(flag1==0)
{
return 1;
}
}
if(l==k)
{
return 0;
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
l=1;
scanf("%d",&n);
for(int i=0; i<n; i++)
{
scanf("%d",&sz[0].a[i]);
}
for(int i=0; i<n; i++)
{
scanf("%d",&s[i]);
}
if(bfs()==1)
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
}
问题有两个
(1)如何判重(若用数组储存来判重,内存不够)
(2)这个结构体开不大,不够用,开大就无法运行
其实这可以合并为一个问题,数据太大,没办法开很大的数组来储存 然后 广搜的方法就被排除了(其实还是能运行出第一个样例的)
纠结了很长时间,看了看大神的代码
大神有数学方法
因为变化规律是 (Ai-1,Ai,Ai+1)—>(Ai-1 + Ai,-Ai,Ai+1+Ai)
发现 变化前 前一个数和 Ai-1 前两个数和 Ai-1 + Ai 前三个 Ai-1+Ai + Ai+1
变化后 前一个 Ai-1+Ai 前两个 Ai-1 前三个 Ai-1+Ai + Ai+1
前几个数之和没变,只是顺序变化了
那就求出前几个数之和,然后排序一下再比较
如果不排序一个一个找,那样数据太大,复杂度是 n^2
下面大牛代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int a[1000000],b[1000000];
int c[1000000],d[1000000];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
c[i]=c[i-1]+a[i];
}
for(int i=1;i<=n;i++)
{
scanf("%d",&b[i]);
d[i]=d[i-1]+b[i];
}
sort(c+1,c+n+1);
sort(d+1,d+n+1);
int sum=0;
for(int i=1;i<=n;i++)
{
if(c[i]==d[i])
{
sum++;
}
}
if(sum==n)
{
printf("Yes\n");
}
else
printf("No\n");
}
}
总结;有时候一般方法不行的话就要靠数学方法了,不要不行了还一直想,
一棵树上吊死。
还是数学方法吊,好好学习数学