目录
E - Tian Ji -- The Horse Racing
A - FatMouse' Trade
可拆分物品的背包
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define FI first
#define SE second
#define MP make_pair
#define PII pair<int,int>
const LL mod = 1e9+7;
const int LG = 50;
const int MX = 1e6+5;
PII a[MX];
bool cmp(PII x,PII y){
return x.FI*y.SE>y.FI*x.SE;
}
int main(){
int n,m;while(cin>>m>>n){
if(m==-1)break;
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].FI,&a[i].SE);
}
sort(a+1,a+1+n,cmp);
double ans=0;
for(int i=1;i<=n;i++){
if(m>=a[i].SE){
m-=a[i].SE;
ans=ans+(double)a[i].FI;
}
else {
ans=ans+(double)a[i].FI*(double)m/(double)a[i].SE;
m=0;
}
if(m==0)break;
}
printf("%.3lf\n",ans);
}
return 0;
}
B - Schedule
题意:安排所有活动需要房间数量问题,并求出Σ(所有房间的使用时长)。
思路:首先对于所有的活动,先开始的优先,用map记录一个房间的开始时间和结束时间模拟。
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define FI first
#define SE second
#define MP make_pair
#define PII pair<int,int>
const LL mod = 1e9+7;
const int LG = 50;
const int MX = 1e6+5;
PII a[MX];
bool cmp(PII x,PII y){
return x.FI<y.FI;
}
multiset<PII>e;
int main(){
int T;cin>>T;while(T--){
int n;cin>>n;e.clear();
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].FI,&a[i].SE);
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
auto id=e.lower_bound(MP(a[i].FI,INT_MAX));
if(id==e.begin()){
e.insert(MP(a[i].SE,a[i].FI));
}
else {
id--;
int zz=id->SE;
e.erase(id);
e.insert(MP(a[i].SE,zz));
}
}
LL ans=0;
for(auto i:e){
ans=ans+(LL)(i.FI-i.SE);
}
cout<<e.size()<<' '<<ans<<'\n';
}
return 0;
}/*
5
5
1 3
12 15
2 5
4 8
3 6
3
1 3
4 6
2 5
*/
C - Gene Assembly
题意:一个房间最多能安排多少活动问题。
思路:贪心安排先结束的
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define FI first
#define SE second
#define MP make_pair
#define PII pair<int,int>
const LL mod = 1e9+7;
const int LG = 50;
const int MX = 1e6+5;
map<int,vector<int> >ma;
map<PII ,int>zz;
vector<int>v;
int main(){
int n;
while(cin>>n){
if(n==0)break;
v.clear(),zz.clear(),ma.clear();
for(int i=1;i<=n;i++){int l,r;scanf("%d%d",&l,&r);ma[r].push_back(l);zz[MP(l,r)]=i;}
for(map<int,vector<int> >::iterator i=ma.begin();i!=ma.end();i++){
sort(i->SE.begin(),i->SE.end());reverse(i->SE.begin(),i->SE.end());
}
int R=0;
for(map<int,vector<int> >::iterator i=ma.begin();i!=ma.end();i++){
if(i->SE[0]<R)continue;
else R=i->FI,v.push_back(zz[MP(i->SE[0],i->FI)]);
}
printf("%d",v[0]);
for(int i=1;i<(int)v.size();i++) printf(" %d",v[i]);
puts("");
}
return 0;
}
D - Pass-Muraille
贪心删除对右边影响大的
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define FI first
#define SE second
#define MP make_pair
#define PII pair<int,int>
const LL mod = 1e9+7;
const int LG = 50;
const int MX = 1e6+5;
int mp[105][105];
int R[105];
int main(){
int T;cin>>T;while(T--){
int n,k;cin>>n>>k;
for(int i=0;i<=100;i++)for(int j=0;j<=100;j++)mp[i][j]=0;
for(int i=1;i<=n;i++){
int a,b,c,d;cin>>a>>b>>c>>d;
if(a>c)swap(a,c);
R[i]=c;
for(int j=a;j<=c;j++){
mp[j][b]=i;
}
}
int ans=0;
for(int i=0;i<=100;i++){
int z=0;
for(int j=0;j<=100;j++){
if(mp[i][j]) z++;
}
while(z>k){
ans++;z--;
int mx=-1,u;
for(int j=0;j<=100;j++){
if(mp[i][j]&&R[mp[i][j]]>mx)mx=R[mp[i][j]],u=j;
}
int jjj=R[mp[i][u]];
for(int j=i;j<=jjj;j++)
mp[j][u]=0;
}
}
cout<<ans<<'\n';
}
return 0;
}
E - Tian Ji -- The Horse Racing
题意:田忌赛马,赢了+100,输了-100,平局+0,求最多田忌的得分。
思路:能赢尽量赢,如果输,拿最坏的马输给对方最好的马
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define PII pair<int,int>
const int MX =510;
int main(){
int n;while(cin>>n){
if(!n)break;int a[1005],b[1005];
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
sort(a+1,a+1+n);sort(b+1,b+1+n);
reverse(a+1,a+1+n);reverse(b+1,b+1+n);
deque<int>w;deque<int>t;
int ans=0;
for(int i=1;i<=n;i++)t.push_back(a[i]);
for(int i=1;i<=n;i++)w.push_back(b[i]);
for(int i=1;i<=n;i++){
if(t.front()>w.front()) ans++,t.pop_front(),w.pop_front();
else if(t.front()<w.front()) ans--,t.pop_back(),w.pop_front();
else if(t.back()>w.back()) ans++,t.pop_back(),w.pop_back();
else if(t.back()<w.back()) ans--,t.pop_back(),w.pop_front();
else ans-=(t.back()<w.front()),t.pop_back(),w.pop_front();
}
cout<<ans*200<<'\n';
}
return 0;
}
F - Wooden Sticks
题意:n个x*y的方块,如果x1<=x2&&y1<=y2,那么x1可以放在x2上面,求最少放几堆。
思路:按照x为第一关键字,y为第二关键字排序,然后一直找最长上升子序列。
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define PII pair<int,int>
const int MX =1e6+5;
pair<int,int>a[5005];
int vis[5005];
bool cmp(pair<int,int>x,pair<int,int>y){
if(x.FI==y.FI)return x.SE<y.SE;
return x.FI<y.FI;
}
int main(){
int T;cin>>T;while(T--){
int n;cin>>n;
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i].FI,&a[i].SE);
}
sort(a+1,a+1+n,cmp);int ans=0;
for(int i=1;i<=n;i++){
if(vis[i])continue;
vis[i]=1;ans++;
PII now=a[i];
for(int j=i+1;j<=n;j++){
if(!vis[j]&&a[j].FI>=now.FI&&a[j].SE>=now.SE) now=a[j],vis[j]=1;
}
}
cout<<ans<<'\n';
}
return 0;
}
G - Radar Installation
题意:n个岛屿,至少在x轴放几个雷达,能使所有岛屿到最近的雷达距离<=R。
思路:以每个岛屿为中心点画半径为R的圆,那么可以在x轴上得到许多个区间。
然后从左到右遍历每一个区间,维护右端点的最小值,贪心的加雷达。
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define PII pair<int,int>
const int MX =1e4;
pair<double,double> a[MX];
int main(){
int casen=0;
int n,d;while(cin>>n>>d&&n){
int tag=0;
for(int i=1;i<=n;i++){
double sx,sy;scanf("%lf%lf",&sx,&sy);
a[i].FI=(double)sx-(double)sqrt(d*d-sy*sy);a[i].SE=(double)sx+(double)sqrt(d*d-sy*sy);
if(sy>d) tag=1;
}
if(tag){printf("Case %d: -1\n",++casen);continue;}
sort(a+1,a+1+n);
double R=a[1].SE;int ans=1;
for(int i=2;i<=n;i++){
if(a[i].FI<=R) R=min(R,a[i].SE);
else ans++,R=a[i].SE;
}
printf("Case %d: %d\n",++casen,ans);
}
return 0;
}
H - Copying Books
题意:将数组分成k块,使和最大的那一块的和最小。
思路:二分那个最小的和,因为输出的时候,要使越前面的和越小,那么从后往前分,并标记。
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define FI first
#define SE second
#define LL long long
#define PII pair<int,int>
const int MX =510;
int a[MX],path[MX],ans[MX];int n,m;
bool check(LL x){
memset(path,0,sizeof(path));
int cnt=m;LL sum=0;
for(int i=n;i>=1;i--){
if(cnt==i+1) cnt--,path[i]=1;
else if(sum+(LL)a[i]>x) sum=(LL)a[i],cnt--,path[i]=1;
else sum+=(LL)a[i];
}
if(cnt<1)return 0;
return 1;
}
int main(){
int T;cin>>T;while(T--){
cin>>n>>m;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
LL l=0,r=1e12;
for(int i=1;i<=n;i++)l=max(l,(LL)a[i]);
while(l<=r){
LL mid=(l+r)/2;
if(check(mid)){
for(int i=1;i<=n;i++)ans[i]=path[i];
r=mid-1;
}
else l=mid+1;
}
for(int i=1;i<=n;i++){
cout<<a[i];
if(i!=n)cout<<' ';
if(ans[i]) cout<<"/ ";
}
puts("");
}
return 0;
}