题目链接
Consider an array a1,a2,…,an consisting of numbers 1 and −1. Define A-characteristic of this array as a number of pairs of indices 1≤i<j≤n, such that ai⋅aj=1.
Find any array a with given length n with A-characteristic equal to the given value k.
Input
Each test contains multiple test cases. The first line contains the number of test cases t
(1≤t≤100). The description of the test cases follows.
The only line of each test case contains two integers n and k (2≤n≤100; 0≤k≤(n−1)n2) — the length of required array and required A-characteristic.
Output
For each test case, if there is no array a with given A-characteristic k, print NO.Otherwise, print YES and n numbers 1 and −1, which form the required array a. If there are multiple answers, print any of them.
吐槽:
翻译真的…看了半天,才看懂这翻译说什么
题目大意:
t组测试样例,每组给n和k,n表示有一个长度为n的数组a,数组元素取值为1或者-1。
现在题目定义了一个A-characteristic,是两个不相等的i和j(i<j),使得数组a里面a[i]*a[j]=1
这样的一组i,j是一个A-characteristic
现在给你一个n和k,问你有没有一个长度为n的数组a,里面的恰好满足有k个A-characteristic,如果没有就输出NO,否则输出YES和其中一个答案
解题思路
首先要知道 1*1=1 和 -1 * -1 =1,A-characteristic其实就这两种
那么如果一个数组里面有n个1,其实可以用递推公式可以推出来。
首先只有0个或1个1是不可能出现A-characteristic(只考虑1的情况),如果有2个1,A-characteristic就会出现一次,3个出现3次(1+2),四个出现六次(1+2+3),其实就是组合问题。
反过来想-1的情况也是一样,0或者1个-1出现0次,2个出现一次,3个出现三次
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
#define lowbit(x) ((x)&(-(x)))
#define int long long
#define rep(i,a,b) for(int i=(int)a,i##i=(int)b;i<=i##i;i++)
#define per(i,a,b) for(int i=(int)a,i##i=(int)b;i>=i##i;i--)
typedef long long ll;
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N = 1000005;
const double PI = acos(-1);
int a[101]={0,0,1,3,6};
void solve()
{
int n,k;
cin>>n>>k;
int flag=0;int ii;
for(int i=0;i<=n;i++) {
//if(a[i]>k){
// ii=i-1;break;
//}
//else if(a[i]==k){
// ii=i;break;
//}
if (a[(n - i)] + a[i] == k) {//满足条件,有k个A-characteristic
flag = 1;
ii=i;
}
}
int flag2=1;
if(flag){
cout<<"YES\n";
for(int j=0;j<ii;j++){//先打印1
if(flag2)cout<<1;
else cout<<' '<<1;
flag2=0;
}
for(int j=0;j<n-ii;j++){//再打印-1
if(flag2)cout<<-1;
else cout<<' '<<-1;
flag2=0;
}
}
else cout<<"NO\n";//所有情况都不符合
if(flag)
cout<<"\n";
}
signed main()
{
std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
for(int i=5;i<=100;i++){
a[i]=a[i-1]+i-1;//预处理,先推出所有的,可以把递推公式优化为通项公式
}
int _ = 1;
cin>>_;
while(_--)
solve();
}
别人的的代码1:
#include <iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
int t, n, k;
cin>>t;
while(t--){
cin>>n>>k;
bool found = false;
for(int i=n;i>=(n+1)/2;i--){
if((i*(i-1)/2) + ((n-i)*(n-i-1)/2) == k){//通项公式!!
found =true;
cout<<"YES"<<endl;
for(int j=1;j<=n;j++){
cout<<(j<=i?1:-1)<<" ";//确实感觉自己那样写复杂了...
}
cout<<endl;
}
}
if(!found){
cout<<"NO"<<endl;
}
}
return 0;
}
一分钟AC巨佬代码:
//这回只花了114514min就打完了。
//真好。记得多手造几组。ACM拍什么拍。
#include "bits/stdc++.h"
using namespace std;
template<typename typC,typename typD> istream &operator>>(istream &cin,pair<typC,typD> &a) { return cin>>a.first>>a.second; }
template<typename typC> istream &operator>>(istream &cin,vector<typC> &a) { for (auto &x:a) cin>>x; return cin; }
template<typename typC,typename typD> ostream &operator<<(ostream &cout,const pair<typC,typD> &a) { return cout<<a.first<<' '<<a.second; }
template<typename typC,typename typD> ostream &operator<<(ostream &cout,const vector<pair<typC,typD>> &a) { for (auto &x:a) cout<<x<<'\n'; return cout; }
template<typename typC> ostream &operator<<(ostream &cout,const vector<typC> &a) { int n=a.size(); if (!n) return cout; cout<<a[0]; for (int i=1; i<n; i++) cout<<' '<<a[i]; return cout; }
template<typename typC,typename typD> bool cmin(typC &x,const typD &y) { if (y<x) { x=y; return 1; } return 0; }
template<typename typC,typename typD> bool cmax(typC &x,const typD &y) { if (x<y) { x=y; return 1; } return 0; }
template<typename typC> vector<typC> range(typC l,typC r,typC step=1) { assert(step>0); int n=(r-l+step-1)/step,i; vector<typC> res(n); for (i=0; i<n; i++) res[i]=l+step*i; return res; }
#if !defined(ONLINE_JUDGE)&&defined(LOCAL)
#include "my_header\debug.h"
#else
#define dbg(...) ;
#define dbgn(...) ;
#endif
typedef unsigned int ui;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
// template<typename T1,typename T2> void inc(T1 &x,const T2 &y) { if ((x+=y)>=p) x-=p; }
// template<typename T1,typename T2> void dec(T1 &x,const T2 &y) { if ((x+=p-y)>=p) x-=p; }
const int N=1e6+5;
int main()
{
ios::sync_with_stdio(0); cin.tie(0);
cout<<fixed<<setprecision(15);
int T; cin>>T;
while (T--)
{
int n,m,i,j;
cin>>n>>m;
for (i=0; i<=n; i++) if (i*(i-1)/2+(n-i)*(n-i-1)/2==m) break;
if (i>n) cout<<"NO\n";
else cout<<"YES\n"<<vector<int>(i,1)<<' '<<vector<int>(n-i,-1)<<'\n';
}
}
直接cout容器可还行!
确实,i>n就行,不用flag标记!