A. Repeating Cipher(模拟)
题目链接:https://codeforces.com/contest/1095/problem/A
题目大意:n中元素,第一个出现一次,第二个出现两次,一次类推,输出字符串
思路:模拟
AC:
char s[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
clean(s,'\0');
cin>>s;
int l=strlen(s);
int i=1,sum=1;
while(sum<=l)
{
cout<<s[sum-1];
i++;
sum=(1+i)*i/2;
}
cout<<endl;
}
}
B. Array Stabilization(暴力)
题目链接:https://codeforces.com/contest/1095/problem/B
题目大意:给你一个数组,从中删掉一个元素,使得该数组的(最大值-最小值)最小。
思路:拍一下序,然后看删第一个好还是最后一个好。因为ans只由这两个元素决定。
AC:
int arr[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
clean(arr,0);
for(int i=1;i<=n;++i)
cin>>arr[i];
sort(arr+1,arr+1+n);
int ans;
ans=min(arr[n]-arr[2],arr[n-1]-arr[1]);
cout<<ans<<endl;
}
}
C. Powers Of Two(暴力)
题目链接:https://codeforces.com/contest/1095/problem/C
题目大意:一个数n,能被拆分成m个2的次幂个数吗,YES,输出这些数,否则NO
思路:m大于n的话必定不可能,然后找n这个数的最少的分解数(二进制数),如果m再[min,n]之间的话为YES,否则为NO
AC:
int arr[MAXN];
int main()
{
std::ios::sync_with_stdio(false);
int n,k;
while(cin>>n>>k)
{
clean(arr,0);
int res=n,ecnt=0,a=1;
while(res)
{
if(res&1)
arr[ecnt++]=a;
a=a<<1;
res=res>>1;
}
if(k>=ecnt&&k<=n)
{
cout<<"YES"<<endl;
int cnt=k-ecnt;
for(int i=0;i<ecnt;++i)
{
while(cnt&&arr[i]!=1)
{//�����Ҫ�� && ���Է�
arr[ecnt++]=arr[i]>>1;
arr[i]=arr[i]>>1;
cnt--;
}
}
for(int i=0;i<ecnt;++i)
cout<<arr[i]<<" ";
}
else
cout<<"NO"<<endl;
}
}
D. Circular Dance(规律)
题目连接:https://codeforces.com/contest/1095/problem/D
题目大意:一些小朋友做成一圈,然后打乱了顺序,每个小朋友只记得它前面的小朋友是谁(前面一个||前面两个),然后让你重新得出小朋友的座次
思路:挑选两个小朋友即可固定座位,主要使题意不好理解。。
AC:
int vis[MAXN],arr[MAXN][5];
int main()
{
std::ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
clean(arr,0);
clean(vis,0);
for(int i=1;i<=n;++i)
cin>>arr[i][1]>>arr[i][2];
cout<<1;
vis[1]=1;
int res=n-1,i=1;
while(res--)
{
if((arr[arr[i][1]][1]==arr[i][2]||arr[arr[i][1]][2]==arr[i][2])&&vis[arr[i][1]]==0)
{//������ i - a11 - a12
cout<<" "<<arr[i][1];
vis[arr[i][1]]=1;
i=arr[i][1];
}
else
{//����һ��· i - a12 - a11
cout<<" "<<arr[i][2];
vis[arr[i][2]]=1;
i=arr[i][2];
}
}
cout<<endl;
}
}
F. Make It Connected(并查集)
题目链接:https://codeforces.com/contest/1095/problem/F
题目大意:给你n个点,m条边,问使这个图变成连通图的最下小花费是多少,(可以自己造边,val=v1+v2)
思路:并查集板子。首先定点按val排序,然后每次和最小的节点比较即可。然后并查集联通图
AC:
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
const int MAXN=2e5+10;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll mod=1e9+7;
const double PI=acos(-1.0);
pair<pair<ll,ll>,ll> pir[MAXN<<1];
ll val[MAXN];
int pre[MAXN];
int n,m,mini;
void intt()
{
mini=1;
clean(val,0);
for(int i=1;i<=n;++i)
pre[i]=i;
}
bool cmp(const pair<pair<ll,ll>,ll> a,const pair<pair<ll,ll>,ll> b)
{
return a.second<b.second;
}
int find(int x)
{
int res=x;
while(pre[x]!=x)
x=pre[x];
while(pre[res]!=x)
pre[res]=x;
return x;
}
void mix(int x,int y)
{
int fx=find(x),fy=find(y);
pre[fy]=pre[fx];
}
int main()
{
std::ios::sync_with_stdio(false);
while(cin>>n>>m)
{
intt();
for(int i=1;i<=n;++i)
{
cin>>val[i];
if(val[i]<val[mini])
mini=i;
}
for(int i=1;i<=n;++i)//��i��ͨ����̾���=minn+i
pir[i]={{i,mini},val[i]+val[mini]};
ll a,b,v;
for(int i=1;i<=m;++i)
{
cin>>a>>b>>v;
pir[i+n]={{a,b},v};
}
sort(pir+1,pir+n+m+1,cmp);
ll ans=0;
for(int i=1;i<=n+m;++i)
{
if(find(pir[i].first.first)!=find(pir[i].first.second))
{
ans+=pir[i].second;
mix(pir[i].first.first,pir[i].first.second);
}
}
cout<<ans<<endl;
}
}