图片排版
题目链接:
http://hihocoder.com/problemset/problem/1365解题思路:
比较容易想到是O(n^2)的解决方案,遍历n种删除可能,每次遍历O(n)时间求总高度。前者优化比较困难,因而想办法优化每次遍历求高度的时间。
由前往后遍历,当删除第i个图片时,先前的图片排版是连续的,从而通过计数器等累加方法可以求得已完整行的总高度preSum,以及当前未完整行的w,h。
AC代码:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using 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]));
else
h = 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;
}