[Offer收割]编程练习赛7

来源:互联网 发布:网络克隆系统教程 编辑:程序博客网 时间:2024/04/29 05:23

图片排版

题目链接:

http://hihocoder.com/problemset/problem/1365

解题思路:

比较容易想到是O(n^2)的解决方案,遍历n种删除可能,每次遍历O(n)时间求总高度。
前者优化比较困难,因而想办法优化每次遍历求高度的时间。
由前往后遍历,当删除第i个图片时,先前的图片排版是连续的,从而通过计数器等累加方法可以求得已完整行的总高度preSum,以及当前未完整行的w,h。

AC代码:

#include<bits/stdc++.h>#define INF 0x3f3f3f3fusing namespace std;const int N = 100005;int n,m;int wi[N],hi[N],t[N];void attach(int i,int &w,int &h){if (w+wi[i] > m)h = max(h,(int)ceil(1.0*(m-w)*hi[i]/wi[i]));elseh = max(h, hi[i]);w = min(m, w+wi[i]);}int calc(int i,int w,int h){while(i < n && w < m)attach(i++,w,h);return h+t[i];}void solve(){int ans = INF,w,h,preSum;w = h = preSum = 0;for(int i = 0; i < n; ++i){int tmp = calc(i+1,w,h);ans = min(ans, preSum+tmp);attach(i,w,h);if(w == m){preSum += h;w = h = 0;}}printf("%d\n",ans);}int main(){while(~scanf("%d%d",&m,&n)){        for(int i = 0; i < n; ++i)            scanf("%d%d",&wi[i],&hi[i]);        for(int i = n-1; i >= 0; --i)            t[i] = calc(i,0,0);        solve();}return 0;}

逆序单词

题目链接:

http://hihocoder.com/problemset/problem/1366

解题思路:

利用map的性质即可轻易求解。

AC代码:

#include<bits/stdc++.h>using namespace std;typedef long long ll;map<string,int> ma;map<string,int>::iterator it;int main(){    int n;    while(~scanf("%d",&n)){        ma.clear();        string str;        for(int i = 0; i < n; ++i){            cin>>str;            int len = str.size();            if(!ma[str]){                reverse(str.begin(),str.end());            }            //cout<<str<<endl;            ++ma[str];        }        ll ans = 0;        for(it = ma.begin(); it != ma.end(); ++it){            ans += (ll)(it->second)*(it->second-1)/2;        }        printf("%lld\n",ans);    }    return 0;}


0 0
原创粉丝点击