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个条件的,最合适的旅店
- 比M近的,没有比M便宜的
- 比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;
}