UVA 12166 dfs+Map库的巧用

来源:互联网 发布:钢铁力量天王战车数据 编辑:程序博客网 时间:2024/06/04 19:17

题意

给一个天平,每次可以修改天平左边或者右边的重量,想让这个天平能够所有天平都能够平衡,求最少需要修改的次数。


思路

最开始拿到这个题,完全没有头绪。

之后想到,如果固定一个砝码,那么就能够求出其余的所有砝码是不是需要修改了。

但是如果暴力模拟每一个砝码,则时间复杂度会超

于是又没有思绪了

再一想,这是一个二叉树,如果平衡了,那么只要知道一个砝码的重量,和砝码的深度,就能够知道整个天平的重量。

那么 ,直接过一遍每一个砝码,计算其天平重量,假如有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 0x3f3f3f3f3fusing 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 以后有机会再来读这段代码

0 0
原创粉丝点击