题意
给一个天平,每次可以修改天平左边或者右边的重量,想让这个天平能够所有天平都能够平衡,求最少需要修改的次数。
思路
最开始拿到这个题,完全没有头绪。
之后想到,如果固定一个砝码,那么就能够求出其余的所有砝码是不是需要修改了。
但是如果暴力模拟每一个砝码,则时间复杂度会超
于是又没有思绪了
再一想,这是一个二叉树,如果平衡了,那么只要知道一个砝码的重量,和砝码的深度,就能够知道整个天平的重量。
那么 ,直接过一遍每一个砝码,计算其天平重量,假如有M个砝码, 总重量为K的数量最多,为N个,那么,只需要修改M-K个砝码,便能够使所有都能够平衡了。
思路想到了
可是实现起来,好像不是那么的好编程。
主要是记录天平总重量,如果开一个vector ,每次遍历一遍,如果有则在那个数字上++,没有就添加到末尾,但是这样,在极限条件下也会超时的
于是编程又搁置了, 除非能够找到一个Lg(n)的查询速度的容器,后来想到Map就是lg(N)的查询,于是查了一下Map,这个题基本解决。
(有些数据结构也能实现这个功能,比如说之前数据结构课上老师讲的那个排序树。但是这毕竟是竞赛,如果能套用现有的容器,何乐而不为)
map的操作自行查阅
wa1
记录数字记录错误
错误低级得汗颜。for(i = x; s[i]<='9'&&s[i]>='0';i++){ t=t*k+s[i]-'0'; k++; }
AC
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include <map>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <sstream>
#include <string>
#define maxn 23
#define inf 0x3f3f3f3f3f
using namespace std;
map <long long,int> q;
string s;
int sum;
void dfs(int x ,int d , int n){ //d为深度
if(x>n)
return;
if(s[x]=='[') //如果有[ d+1 继续搜索
dfs(x+1,d+1,n);
else if(s[x]==',')
dfs(x+1,d,n);
else if(s[x]==']') //如果有] d-1 继续搜索
dfs(x+1,d-1,n);
else{
int k=0;
long long t=0;
int i=0;
for(i = x; s[i]<='9'&&s[i]>='0';i++){
t=t*10+s[i]-'0';
}
sum++;
q[t<<d]++;
dfs(i,d,n);
}
}
int main(){
int t;
scanf("%d",&t);
while(t--){
cin>>s;
q.clear();
sum=0;
dfs(0,0,s.size()-1);
int maxx=0;
for(map <long long,int>::iterator it=q.begin();it!=q.end();++it){
maxx=max(it->second,maxx);
}
printf("%d\n",sum-maxx);
}
}
70ms
附上一个看不懂的代码
#include <bits/stdc++.h>
using namespace std;
int cur = 0;
char str[1024000];
map<long long, int> cnt;
void DFS(int dep)
{
if(isdigit(str[cur])){
long long a = 0;
while(isdigit(str[cur]))
a = a * 10 + str[cur++] - '0';
cnt[a<<dep]++;
}
else{
cur++; DFS(dep + 1);
cur++; DFS(dep + 1);
cur++;
}
}
int main()
{
ios::sync_with_stdio(false);
int T; cin >> T; cin.get();
while(cur = 0, cnt.clear(), T--) {
cin >> str; DFS(0);
int mx = INT_MIN, sum = 0;
for(map<long long, int>::iterator it = cnt.begin(); it != cnt.end(); it++)
sum += it->second, mx = max(mx, it->second);
cout << sum - mx << endl;
}
return 0;
}
短得可怕,而且时间还特别快 20ms 以后有机会再来读这段代码