1. 程式人生 > 實用技巧 >[20200716NOIP提高組模擬T2]平方數遊戲

[20200716NOIP提高組模擬T2]平方數遊戲

題目大意:

  求序列${a_{i}}$,使得$|\sum_{i=1}^{n}a_{i}\cdot i^{2}|_{min}$,其中$a_{i}\in{1,-1}$.

解題思路:

 由打表可以看出,$n\leq 5$時,答案為特殊情況,打表解決;$n\geq 6$時,答案呈10011001......排布,所以其中必有一定規律.

 又由於$n^{2}-(n+1)^{2}-(n+2)^{2}+(n+3)^{2}=-4$可以看出,我們只需列舉[6,13]內的數,然後往後補若干個{1,-1,-1,1,-1,1,1,-1}即可保持答案最小.

code:

 

#include<iostream>
#include
<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<queue> #define mod 19900907 #define R register #define next exnt #define debug puts("mlg") using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long
long ull; inline ll read(); inline void write(ll x); inline void writesp(ll x); inline void writeln(ll x); ll n; ll ans=1234561370120; ll a[55555],b[55555]; inline void dfs(ll x){ if(x==n+1){ ll sum=0; for(R ll i=1;i<=n;i++){ sum+=a[i]*i*i; } if(abs(sum)<ans){ ans
=abs(sum); for(R ll i=1;i<=n;i++) b[i]=a[i]; } return; } a[x]=1; dfs(x+1); a[x]=-1; dfs(x+1); } ll Ans; int main(){ freopen("five.in","r",stdin); freopen("five.out","w",stdout); n=read(); if(n==1)writeln(1),writesp(1); if(n==2)writeln(3),writesp(1),writesp(-1); if(n==3)writeln(4),writesp(1),writesp(1),writesp(-1); if(n==4)writeln(2),writesp(1),writesp(1),writesp(1),writesp(-1); if(n==5)writeln(3),writesp(1),writesp(-1),writesp(1),writesp(1),writeln(-1); if(n<=5) return 0; while(n>13) n-=8,Ans++; dfs(1); writeln(ans); for(R ll i=1;i<=n;i++) writesp(b[i]); for(R ll i=1;i<=Ans;i++) writesp(1),writesp(-1),writesp(-1),writesp(1),writesp(-1),writesp(1),writesp(1),writesp(-1); } inline ll read(){ ll x=0,t=1;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') t=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x*t; } inline void write(ll x){ if(x<0){putchar('-');x=-x;} if(x<=9){putchar(x+'0');return;} write(x/10);putchar(x%10+'0'); } inline void writesp(ll x){ write(x);putchar(' '); } inline void writeln(ll x){ write(x);putchar('\n'); }