A.キャンディーと他の
比率シーケンスを合計して、kとxの式を取得します。kを列挙してください。これは、べき関数であるため、kはそれほど大きくありません。
コード
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n;
cin>>n;
ll k,ans;
for(k=2;;k++){
ll cnt=(1<<k)-1;
if(n%cnt==0){
ans=n/cnt;break;
}
}
cout<<ans<<endl;
}
return 0;
}
B.バランスドアレイ
はnが4である限り分割できます。
私の構成では、偶数部が2iを出力し、奇数部が前半で2i-1を出力し、後半で2i + 1を出力します。
コード
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
cin>>q;
while(q--){
int n;
cin>>n;
n/=2;
if(n%2){
printf("NO\n");
}
else{
printf("YES\n");
for(int i=1;i<=n;i++) cout<<2*i<<" ";
for(int i=1;i<=n;i++){
if(i<=n/2) cout<<2*i-1<<" ";
else cout<<2*i+1<<" ";
}
cout<<"\n";
}
}
return 0;
}
C.代替
サブシーケンスは、指定されたシーケンスが負の数と正の数のシーケンスであることと同等です。各負の部分と各正の部分から数を選択するには、新しい系列を作成し、この系列の合計を最大にします。 。この方法では、各パーツで最大の数を選択するだけで済みます。
コード
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
cin>>q;
while(q--){
int n;
cin>>n;
vector<int> a(n+1);
for(int i=1;i<=n;i++) {cin>>a[i];}
ll ans=0;
ll pre=a[1],now=1234567890;
for(int i=1;i<=n;i++){
now=a[i];
if(pre>0&&now>0){
now=max(pre,now);
pre=now;
}
else if(pre<0&&now<0){
now=max(pre,now);
pre=now;
}
else{
ans+=pre;
pre=now;
}
}
ans+=pre;
cout<<ans<<endl;
}
return 0;
}
D.一定のパリンドロームの合計
各ログとその合計について、cnt配列を使用して合計の発生数を格納できます。また、ログは1つの要素で取得できる合計の範囲のみを変更し、差分配列を使用することもわかります。 Prefは、この範囲の上限と下限を格納するために使用されます。すべての数値を数えた後、差分配列はプレフィックスを合計して、特定のxに対して1回しか操作できない数値グループの数を把握します。すべての可能なxを列挙するには、対応する答えは、xの対数を1回未満取得し、xの対数を減算し、さらに2倍の演算を2回実行してxの対数を取得することです。合計ログからxの対数を差し引いた値が1以下の操作は、2つの操作後のxの対数です。
コード
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
vector<int> a;
map<int,int> cnt,pref;
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n,k;
cin>>n>>k;
a.resize(n);
cnt.clear(),pref.clear();
for(auto &x:a) read(x);
for(int i=0;i<n/2;i++) cnt[a[i]+a[n-i-1]]++;
for(int i=0;i<n/2;i++){
int l=a[i],r=a[n-i-1];
pref[max(l,r)+k+1]--;
pref[min(l,r)+1]++;
}
for(int i=2;i<=2*k;i++){
pref[i]+=pref[i-1];
}
int ans=99999999;
for(int i=2;i<=2*k;i++){
ans=min(ans,pref[i]-cnt[i]+2*(n/2-pref[i]));
}
cout<<ans<<"\n";
}
return 0;
}
E.重み付け
最初にbfsを使用してbfsを使用し、abcを開始点として最短経路を前処理し(各道路の長さは1と見なされ、取得する道路の数)、道路のコストを小から大に分類します。中間点xを見つけて、行く方向がa——x——b——x——cになるようにします。このxは、bにすることもできます。各xについて、行く最も短い方法の数を数えます。 aからxがm道路を、xからbがn道路を、xからcがq道路をとる場合、nを最初のn個の小さなコストに対応させることができます(2回歩く必要があるため)、残りのm + pの道路は以前のn + 1からm + pの小さなコストに対応し、対応する最小コストを得ることができます。xをトラバースして最小値を更新するだけで十分です。
コード
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
vector<vector<int> > mp;
void bfs(int a,vector<int> & d){
queue<int> q;
q.push(a);
d[a]=0;
while(!q.empty()){
int x=q.front();
q.pop();
for(auto i:mp[x]){
if(d[i]!=INF) continue;
d[i]=d[x]+1;
q.push(i);
}
}
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n,m,a,b,c;
cin>>n>>m>>a>>b>>c;
vector<int> p(m);
for(auto &x:p) read(x);
sort(p.begin(),p.end());
mp=vector<vector<int> >(n);
for(int i=0;i<m;i++){
int x,y;
read(x),read(y);
x--;y--;
mp[x].push_back(y);
mp[y].push_back(x);
}
a--;b--;c--;
vector<int> aa(n,INF),bb(n,INF),cc(n,INF);
bfs(a,aa);
bfs(b,bb);
bfs(c,cc);
vector<ll> d(m+1);
for(int i=1;i<=m;i++) d[i]=d[i-1]+p[i-1];
ll ans=1e18;
for(int i=0;i<n;i++){
if(aa[i]+bb[i]+cc[i]>m) continue;
ans=min(ans,d[aa[i]+bb[i]+cc[i]]+d[bb[i]]);
}
cout<<ans<<"\n";
}
return 0;
}
F.並べ替えられたセグメントによる順列の復元
入力は、可変長rの2〜n個の要素をすべて与えます。配列の最初の数値を列挙し、それがfstであると仮定し、fstを含むすべてのフラグメントのfstを削除すると、2番目の要素がrであるフラグメントに1つの要素、つまり[2]が残り、次に[2]を含むすべてのフラグメントの[2]を削除すると、[3]を取得でき、この操作を繰り返すことですべての要素を取得できます。一致する可能性のある配列を見つけたら、入力で指定されたn-1個のフラグメントが満たされているかどうかを確認します。これらのフラグメントは、setで維持するのにより便利です。
コード
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int q;
read(q);
while(q--){
int n;
read(n);
vector<set<int> > segs;
for(int i=0;i<n-1;i++){
int k;
read(k);
set<int> seg;
for(int i=0;i<k;i++){
int x;
read(x);
seg.insert(x);
}
segs.push_back(seg);
}
for(int fst=1;fst<=n;fst++){
bool flag=true;
vector<int> ans;
vector<set<int> > cur=segs;
for(auto & x:cur){
if(x.count(fst)){
x.erase(fst);
}
}
ans.push_back(fst);
for(int i=1;i<n;i++){
int num=0;
int nxt=-1;
for(auto &x:cur){
if(x.size()==1){
++num;
nxt=*x.begin();
}
}
if(num!=1){
flag=false;
break;
}
for(auto & x:cur){
if(x.count(nxt)){
x.erase(nxt);
}
}
ans.push_back(nxt);
}
//check
if(flag){
set<set<int> > all(segs.begin(),segs.end());
for(int i=1;i<n;i++){
set<int> seg;
seg.insert(ans[i]);
bool ok=false;
for(int j=i-1;j>=0;j--){
seg.insert(ans[j]);
if(all.count(seg)){
ok=true;
break;
}
}
if(!ok){
flag=false;
break;
}
}
}
if(flag){
for(auto x:ans){
cout<<x<<" ";
}putchar('\n');
break;
}
}
}
return 0;
}