A. Repeating Cipher
题意:
将一个字符串S的第一个字符写一次,第二个写两次,第三个写三次......得到字符串t,给你t,求S
分析:
根据规则,t的第一个,第二个,第四个,第七个,第十一个......便是S的组成
代码:
#include
#include
#include
using namespace std;
int main()
{
string s;
int n;
cin>>n>>s;
int k = 0;
for(int i=0;i
B. Array Stabilization
题意:
从数组中删除一个值,求数组中(最大-最小的值)最小是多少
分析:
要么删最大,要么删最小
代码:
#include
#include
#include
using namespace std;
const int N = 2e5+55;
int a[N];
int main()
{
int n;
cin>>n;
for(int i=0;i>a[i];
sort(a,a+n);
int b = a[n-1]-a[1];
int c = a[n-2]-a[0];
cout<
C. Powers Of Two
题意:
问一个数 n 能否分成k个2^x形式的数的和
分析:
观察n的二进制下有m个1,那么最少就需要m个,最多无非是n个1相加,k>m时就需要拆分,2^x = 2^(x-1)+2^(x-1),多了一个,所以只要k属于[m,n],就一定可以拆分成k个
代码:
#include
#include
#include
#include
using namespace std;
const int N = 2e5+55;
int a[N];
vector v;
int main()
{
int n,k;
cin>>n>>k;
int sum1 = 0;
for(int i=0; i<31; ++i)
{
if(n&(1<=sum1&&k<=n)
{
cout<<"YES"<1)
{
v[i] = v[i]/2;
v.push_back(v[i]);
}
else i++;
}
for(int i=0; i
D. Circular Dance
题意:
n个人围成一圈,每个人记得他的后面两个人是谁,输出每个人站的位置
分析:
注意:不确定后面两个人顺序,ai_1不一定就挨着第i个人
代码:
#include
#include
#include
#include
using namespace std;
const int N = 2e5+55;
int p[N][2];
int vis[N];
void dfs(int x)
{
if(!vis[x])
{
cout<>n;
for(int i=1; i<=n; ++i)
cin>>p[i][0]>>p[i][1];
dfs(1);
return 0;
}
E. Almost Regular Bracket Sequence
题意:
给你一串括号序列,你可以改变一个位置的括号使得序列合法,求有多少个这样的位置
分析:
用栈来去掉合法的序列,讨论最后栈里剩下的情况
代码:
#include
#include
#include
#include
#include
using namespace std;
const int N = 1e6+66;
char ss[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
stack s;
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
cin>>ss[i];
if(ss[i]==')')
{
if(!s.empty()&&ss[s.top()]=='(') s.pop();
else s.push(i);
}
else s.push(i);
}
if(s.size()==0||n%2||s.size()>2) cout<<0;//很显然
else
{
int a = s.top();s.pop();
int b = s.top();
if(ss[b]==')')
{
if(ss[a]==')') //b位置左边的)都可以改变
{
int ans = 0;
for(int i=1;i<=b;++i)
if(ss[i]==')') ans++;
cout<
F. Make It Connected
题意:
有n个点,每个点有一个权值,在两个点之间连一条边的花费为两点权值之和,还有m条特殊边,加入这条边的花费为w,问使图联通最少花费多少
分析:
使图联通且花费最少,无非是建一颗最小生成树,除了已知的m条边,我们还可以建n*(n-1)/2条边(每两个点一条边),但n很大,建了也存不下,考虑一个点和图联通,它的最小花费一定是和最小权值的点连一条边,于是我们就缩减到了n-1条边,克鲁斯卡尔跑一遍最小生成树就OK了
代码
#include
#include
#include
#include
#define mk make_pair
#define f first
#define s second
using namespace std;
typedef long long ll;
const int MAXN = 2e5+255;
struct node
{
int u,v;
ll w;
};
node e[MAXN<<1];
pair p[MAXN];
bool cmp(pair p1,pair p2)
{
return p1.s>n>>m;
for(int i=1;i<=n;++i)
{
cin>>v;
p[i-1] = mk(i,v);
}
int len = 0;
while(m--)
{
cin>>e[len].v>>e[len].u;
cin>>e[len++].w;
}
sort(p,p+n,cmp);
for(int i=1;i