前言:前幾天晚上打了一場Div1+2後終於上藍,爲了紀念,這周就寫這一場的題解了。
A.Changing Volume
水題,貪心。優先移動5格,然後2格,最後1格。
#include<bits/stdc++.h>
using namespace std;
int T,x,y;
int main()
{
cin>>T;
while(T--)
{
cin>>x>>y;
if(y<x)swap(x,y);
if(x==y)cout<<0<<"\n";
else
{
int tt=(y-x)/5;
cout<<(tt+(y-x-tt*5)/2+(y-x-tt*5)%2)<<"\n";
}
}
}
B.Fridge Lockers
水題。當點數不小於邊數時,若要使每個點至少連兩個邊,只能形成一個大環。
#include<bits/stdc++.h>
using namespace std;
int T,n,m,a;
int main()
{
cin>>T;
while(T--)
{
int sum=0;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a,sum+=a;
if(n==2||m<n)
{
cout<<-1<<"\n";
continue;
}
else cout<<sum*2<<"\n";
for(int i=0;i<n;i++)
cout<<(i)%n+1<<" "<<(i+1)%n+1<<"\n";
}
}
C.League of Leesins
觀察發現當時,和只存在於一個三元組,和只存在於兩個三元組,其他元素都存在於三個三元組。所以可以記錄每個數字的出現次數和所屬的三元組,然後從出現次數爲的數字所載的三元組開始刪除(出現次數–),然後尋找下一個出現次的數,刪除順序就是答案。時間複雜度
注意刪到最後會出現一個次數爲的三元組,此時應根據其最初出現次數由大到小放進答案,否則親身試驗會WA2(
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int T,n,m,a[N],vis[N],pre[N],v[N];
int t[N][3];
vector<int> G[N],ans;
bool cmp(int a,int b)
{
return pre[a]>pre[b];
}
void dfs(int x)
{
if(vis[x]==1)
{
ans.push_back(x);
for(int j=0;j<G[x].size();j++)
{
if(v[G[x][j]])continue;
int* tmp=t[G[x][j]];
v[G[x][j]]=1;
if(vis[tmp[0]]==1&&vis[tmp[1]]==1&&vis[tmp[2]]==1)
{
ans.pop_back();
sort(tmp,tmp+3,cmp);
for(int k=0;k<3;k++)
ans.push_back(tmp[k]);
for(int k=0;k<n;k++)cout<<ans[k]<<" ";
exit(0);
}
for(int i=0;i<3;i++)vis[tmp[i]]--;
for(int i=0;i<3;i++)dfs(tmp[i]);
}
}
}
int main()
{
cin>>n;
for(int i=1;i<=n-2;i++)
for(int j=0;j<3;j++)
{
cin>>t[i][j];
vis[t[i][j]]++;
pre[t[i][j]]++;
G[t[i][j]].push_back(i);
}
for(int i=1;i<=n;i++)
dfs(i);
}
D.Feeding Chicken
首先算出即爲每種顏色最低分配的的數量,我們可以從上到下型貪心塗色。對於前個來說,每個的顏色都是相同的;在這之後,每個塗一種顏色即可。時間複雜度
#include<bits/stdc++.h>
using namespace std;
int T,n,m,k;
char a[111][111];
vector<char> c;
int main()
{
for(char i='a';i<='z';i++)c.push_back(i),c.push_back(i-'a'+'A');
for(char i='0';i<='9';i++)c.push_back(i);
scanf("%d",&T);
while(T--)
{
int cnt=1,num=0;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
{
scanf("%s",a[i]+1);
for(int j=1;j<=m;j++)cnt+=(a[i][j]=='R');
}
for(int i=1;i<=n;i++)
if(i&1)
for(int j=1;j<=m;j++)
{
if(a[i][j]=='R')num++;
a[i][j]=c[num*k/cnt];
}
else
for(int j=m;j>=1;j--)
{
if(a[i][j]=='R')num++;
a[i][j]=c[num*k/cnt];
}
for(int i=1;i<=n;i++)
printf("%s\n",a[i]+1);
}
}
E1&2.Send Boxes to Alice
令表示所給數列前項之和,若使所有盒子裏的數都能被大於的數整除,則必是的質因子。因此,我們可以預處理出所有可能的素因子。
對於每一個,設位置之前都滿足(能被整除),則對於第個位置來說,若要滿足題目條件,只能將第個位置的數減少(從向後分)或增加(從之後向分),對答案的貢獻即爲。枚舉所有可能的併線性時間內處理答案取最小值即可。時間複雜度,爲的素因子個數,爲之內的常數。
#include <bits/stdc++.h>
#define ll long long
#define N 1000010
using namespace std;
int n;
ll a[N],sum[N],tmp,ans=(1LL<<60);
vector<ll> fac;
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],sum[i]=sum[i-1]+a[i];
tmp=sum[n];
if(tmp==1)
{
cout<<-1;
return 0;
}
for(ll i=2;i*i<=tmp;i++)
if(tmp%i==0)
{
while(tmp%i==0)tmp/=i;
fac.push_back(i);
}
if(tmp>1)fac.push_back(tmp);
for(auto it:fac)
{
ll s=0;
for(int i=1;i<n;i++)
s+=min(sum[i]%it,it-sum[i]%it);
ans=min(ans,s);
}
cout<<ans;
}
F.Point Ordering
未完待續