作天宿舍停电没有打成,今天补了一下题目。
A题,我读的题意是所有包的和应该是N,随手猜了个规律,果然不对。。。然后因为所有包是全用或全不用,感觉像时二进制,但总觉得这样所有包的和就不是N 了。。不是很明白。求一下数的二进制长度,过了。
B题,有两个操作,是一个数加1或减1,问你最少的操作次数,使得学列中位数是不是等于s。思考一下,发现只需要判断中位数和S的大小关系就行了。如果是小与,就从Mid往后找,找到第一大于等于S的数停止,把这个范围的数全部加到S就行了。
同理如果是大于,就从Mid往前找,找到第一个小于等于S的数停止。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 2e5+10;
typedef long long ll;
ll N,S;
ll a[MAX];
int main(void){
scanf("%I64d%I64d",&N,&S);
for(int i=1;i<=N;++i){
scanf("%I64d",&a[i]);
}
ll Mid = N/2+1;
sort(a+1,a+1+N);
ll sum = 0;
if(a[Mid] <= S){
for(int i=Mid;i<=N;++i){
sum += (S-a[i]);
if(i != N && a[i] <= S && a[i+1] > S)
break;
}
printf("%I64d\n",sum);
}
else{
for(int i=Mid;i>=1;--i){
sum += (a[i]-S);
if(i != 1 && a[i] >= S && a[i-1] < S)
break;
}
printf("%I64d\n",sum);
}
return 0;
}
C题,感觉这个比B题简单点。给你两个二进制串s,t,你可以对s进行两种操作,一种交换i,j位置的数,代价为|i-j|,另一种把某个位置数取反代价为1。问你最小的代价使得s变为t。
很显然,只有相邻的两个会进行第一种操作,因为如果距离大于1,第一种操作不如第二种操作。直接扫描s,当某个位置不同,判断相邻的后一个位置是否不同,且与当前这个位置的t相同。就进行第一种操作,其他都进行第二种操作。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1e6+10;
char a[MAX],b[MAX];
void filp(char &ch){
if(ch == '0')
ch = '1';
else
ch = '0';
}
int main(void){
int N;
scanf("%d",&N);
scanf("%s",a+1);
scanf("%s",b+1);
int res = 0;
for(int i=1;i<=N;++i){
if(a[i] != b[i]){
if(i == N){
res++;
filp(a[i]);
}
else{
if(a[i+1] == b[i+1]){
res++;
filp(a[i]);
}
else{
if(a[i] == a[i+1]){
res++;
filp(a[i]);
}
else{
res++;
swap(a[i],a[i+1]);
}
}
}
}
}
printf("%d\n",res);
// printf("%s\n",a+1);
return 0;
}
D题:给你个树,在给你个序列,问你这个序列是不是bfs序列的一个结果。
这个题树是无向图,看错了。WA了好几次哎。。而且BFS序列和下一层序列和上一层的放入顺序也有关系。这里也要判断。
就是先把树分层,判断序列对应的是不是与该层相同,再对这层的孩子与对应序列判断。
感觉自己写的很麻烦
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int MAX = 2e5+10;
vector<int> G[MAX],lay[MAX];
int seq[MAX];
bool used[MAX];
set<int> son[MAX];
int top;
void bfs(){
memset(used,false,sizeof(used));
queue<int> que;
top = 0;
lay[top].push_back(1);
top++;
que.push(1);
used[1] = true;
while(!que.empty()){
int u = que.front();que.pop();
for(int i=0;i<G[u].size();++i){
int v = G[u][i];
if(!used[v]){
used[v] = true;
son[u].insert(v);
lay[top].push_back(v);
}
}
if(que.empty()){
if(lay[top].size() != 0){
for(int i=0;i<lay[top].size();++i){
que.push(lay[top][i]);
}
top++;
}
}
}
}
bool Equal(vector<int> A,vector<int> B){
sort(A.begin(),A.end());
sort(B.begin(),B.end());
if(A.size() != B.size()) return false;
for(int i=0;i<A.size();++i)
if(A[i] != B[i])
return false;
return true;
}
bool solve(){
if(seq[1] != 1 ) return false;
bfs();
int l = 1,r = 1;
for(int i=0;i<top;++i){
r = l + lay[i].size();
vector<int> vec;
for(int j=l;j<r;++j)
vec.push_back(seq[j]);
if(!Equal(vec,lay[i])) return false;
l = r;
if(i == top-1) break;
for(int j=0;j<vec.size();++j){
int u = vec[j];
vector<int> temp;
for(int k=r;k<r+son[u].size();++k)
temp.push_back(seq[k]);
vector<int> ss;
for(set<int>::iterator it = son[u].begin();it != son[u].end();++it){
ss.push_back(*it);
}
if(!Equal(temp,ss)) return false;
r += son[u].size();
}
}
return true;
}
int main(void){
int N;
scanf("%d",&N);
int u,v;
for(int i=1;i<=N-1;++i){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
for(int i=1;i<=N;++i){
scanf("%d",&seq[i]);
}
if(solve()) printf("Yes\n");
else printf("No\n");
return 0;
}
/*
7
1 2
1 3
2 4
2 5
3 6
3 7
1 3 2 4 5 6 7
7
1 2
1 3
2 4
2 5
3 6
3 7
1 2 3 4 5 6 7
*/