灵动ICPC冬令营基础-5

A - Brainman

题意: 求给定序列的逆序对
思路:
可以使用归并排序,或者树状数组

/********************
*author:
*topic:mergesort
*source:灵动ICPC冬令营基础-5
A - Brainman
POJ 1804 
*******************/
#include <iostream>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cstdio>
#define ll long long
using namespace std;

const int N = 1e5+7;
int n,cas,a[N],t[N];
ll ans = 0;
void mergersort(int x,int y) {
	if(y-x <=1) return ;
	int mid = x+(y-x)/2;
	mergersort(x,mid);
	mergersort(mid,y);
	int q = x,p = mid,i=x;
	while(q < mid || p < y) {
		if(q >= mid || (p < y && a[q] > a[p])) {
			ans += (ll)mid-q;
			t[i++] = a[p++];
		}
		else {
			t[i++] = a[q++];
		}
	}
	for(int i = x; i < y; i++)
		a[i] = t[i];
}
int main(){
	scanf("%d",&cas);
	for(int icas = 1; icas <= cas; ++icas){
		ans = 0;
		scanf("%d",&n);
		for(int i = 1; i <= n; ++i)
			scanf("%d",&a[i]);
		mergersort(1,n+1);
		printf("Scenario #%d:\n",icas);
		printf("%lld\n\n",ans);
	} 
	return 0;
}
B - Ultra-QuickSort

题意:
求逆序对个数
同上

/********************
*author:
*topic:
*source:灵动ICPC冬令营基础-5
POJ 2299
*******************/
#include <iostream>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cstdio>
#define ll long long
using namespace std;

const int N = 5e5+7;
int n;
ll a[N],t[N],ans = 0; 
void mergesort(int x,int y){
	if(y - x == 1) return ;
	int mid = x + (y-x)/2; 
	mergesort(x,mid);
	mergesort(mid,y); 
	int q = x,p = mid,i = x;
	while(q < mid || p < y){
		if(q >= mid || (p < y && a[p] < a[q])){
			t[i++] = a[p++];
			ans += (ll)mid - q;
		}else{
			t[i++] = a[q++];
		} 
	}
	for(int j = x; j < y; ++j){
		a[j] = t[j];
	}
}
int main(){
	while(scanf("%d",&n) && n){
		ans = 0;
		for(int i = 1; i <= n; ++i)
			scanf("%lld",&a[i]);
		mergesort(1,n+1);
		printf("%lld\n",ans);
	}
	return 0;
}
C - Who’s in the Middle

题意:排序,求中间的数,本次使用归并

/********************
*author:
*topic:
*source:灵动ICPC冬令营基础-5
C - Who's in the Middle
USACO_04 Nov  POJ2388
*******************/
#include <iostream>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cstdio>
#define ll long long
using namespace std;

const int N = 1e5+7;
int n;
ll a[N],t[N];
ll ans = 0;
void mergesort(int x,int y){
	if(y - x == 1) return ;
	int mid = x + (y-x) / 2;
	mergesort(x,mid);
	mergesort(mid,y);
	int q = x,p = mid,i = x;
	while(q < mid || p < y){
		if(q >= mid || (p < y && a[p] < a[q])){
			t[i++] = a[p++];
			ans += (ll)mid - q;
		}else{
			t[i++] = a[q++];
		}
	}
	for(int j = x; j < y; ++j) 
		a[j] = t[j];
} 
int main(){
	scanf("%d",&n); 
	for(int i  = 1; i <= n; ++i)
		cin>>a[i];
	mergesort(1,n+1);
	cout<<a[n/2+1]; 
	return 0;
}
D - Word Amalgamation

题意: 先给出字典中的一些单词,除此之外再给一些单词,问这些单词是否和字典中的单词一致(一致指单词的字母一样,不考虑顺序)
思路:
将字典单词和待判断单词排序后依次比较

/********************
*author:
*topic:
*source:灵动ICPC冬令营基础-5

*******************/
#include <iostream>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cstdio>
#define ll long long
using namespace std;

const int N = 107;
int n;
string dict[N],ans[N],tmp[N];
string str,str1;
int main(){
	freopen("data.in","r",stdin);
	freopen("data.out","w",stdout);
    int k=0,i,t;
    while(cin>>str1,str1!="XXXXXX"){
        tmp[k]=str1;
        dict[k]=str1;
        sort(dict[k].begin(),dict[k].end());
        k++;
    }
    while(cin>>str,str!="XXXXXX"){
        for(i=0;i<105;i++)
            ans[i].clear();
        t=0;
        sort(str.begin(),str.end());
        for(i=0; i<k; i++)
            if(dict[i]==str)
                ans[t++]=tmp[i];
        if(t==0)
            cout<<"NOT A VALID WORD"<<endl;
        sort(ans,ans+t);
        for(i=0;i<t;i++)
            cout<<ans[i]<<"\n";
        cout<<"******"<<"\n";
    }
    return 0;
}

E -

**题意:**将学生成绩按总分排序,输出过线学生学号和成绩,注意cin输入可能超时。

/********************
*author:
*topic:
*source:灵动ICPC冬令营基础-5
E - 排名
HDOJ 1236
*******************/
#include <iostream>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cstdio>
#define ll long long
using namespace std;

const int N = 1007;
int n,m,line;
int sc[N],k,q;
struct stu{
	char id[27];
	int score;
}s[N];
int ans[N];
bool cmp(const stu &a,const stu &b){
	if(a.score == b.score)
		if(strcmp(a.id,b.id) == -1) 
			return true;
		else
			return false;
	return a.score > b.score;
}
int main(){
	while(scanf("%d",&n) && n){
		scanf("%d %d",&m,&line);
		for(int i = 1; i <= m; ++i)
			scanf("%d",&sc[i]);
		for(int i = 1; i <= n; ++i){
			scanf("%s %d",s[i].id,&k);
			s[i].score = 0; 
			for(int j = 1; j <= k; ++j){
				scanf("%d",&q);
				s[i].score += sc[q];
			}
		}
		sort(s+1,s+n+1,cmp); 
		int cnt = 0;
		for(int i = 1; i <= n; ++i)
			if(s[i].score >= line) ans[++cnt] = i; 
		printf("%d\n",cnt);
		for(int i = 1; i <= cnt; ++i)
			printf("%s %d\n",s[ans[i]].id,s[ans[i]].score);
		
	}

	return 0;
}
F - Election Time

题意: 先按第一次投票排序选出k人,再按第二次投票,选出总统,结构体排序。

/********************
*author:
*topic:
*source:灵动ICPC冬令营基础-5
F - Election Time
POJ_3664
*******************/
#include <iostream>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cstdio>
#define ll long long
using namespace std;
const int N = 5e4 + 7;
struct Cow{
	int first,second;
	int index;
}c[N];

bool cmp(const Cow &a,const Cow &b){
	return a.first>b.first;
} 

int main(){
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>c[i].first>>c[i].second;
  		c[i].index=i;
	}
	sort(c+1,c+n+1,cmp);
	int maxx=0,b;
	for(int i=1;i<=k;i++){
		if(c[i].second > maxx){
			maxx=c[i].second;
			b=c[i].index;
		}
	}
	printf("%d\n",b);
	return 0;
}
G - Holiday Hotel

题意:

找到满足以下2个条件的,最合适的旅店

  1. 比M近的,没有比M便宜的
  2. 比M便宜的,没有比M近的

求有多少个这样的旅店?

思路:

结构体排序,先按价格从小到大排列,价格相同再按距离从小到大排序。
按照价格从小到大遍历,默认选择最便宜的,因为无论后面的距离比最便宜的远还是近,都可以满足条件1,条件2不存在更便宜的情况。
在遍历的过程中,找只要找到一个比之前扫过距离的最小值还小的M,那么M就是候选酒店。后边的比M贵的,无论是比M近还是远都没有关系。

/********************
*author:
*topic:
*source:灵动ICPC冬令营基础-5

*******************/
#include <iostream>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cstdio>
#define ll long long
using namespace std;

const int N = 1e5+7;
const int INF = 0x3f3f3f3f;
int n;
struct hotel{
	int dist,cost;
}h[N]; 
bool cmp(const hotel &a, const hotel &b){
	if(a.cost == b.cost){
		return a.dist < b.dist;
	}
	return a.cost < b.cost;
}
int main(){
	while(scanf("%d",&n) && n){
		for(int i = 1; i <= n; ++i)
			scanf("%d %d",&h[i].dist,&h[i].cost);
		sort(h+1,h+n+1,cmp);
		int min_d = h[1].dist;
		int ans = 1;
		for(int i = 2; i <= n; ++i){
			if(min_d > h[i].dist){
				min_d = h[i].dist;
				ans++;
			}
		}
		printf("%d\n",ans);
	} 
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值