資訊學奧賽一本通(C++版)第二部分 基礎演算法 第二章 資料排序
第二章 資料排序
T1310 : 車廂重組
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
在一箇舊式的火車站旁邊有一座橋,其橋面可以繞河中心的橋墩水平旋轉。一個車站的職工發現橋的長度最多能容納兩節車廂,如果將橋旋轉度,則可以把相鄰兩節車廂的位置交換,用這種方法可以重新排列車廂的順序。於是他就負責用這座橋將進站的車廂按車廂號從小到大排列。他退休後,火車站決定將這一工作自動化,其中一項重要的工作是編一個程式,輸入初始的車廂順序,計算最少用多少步就能將車廂排序。
【輸入】
有兩行資料,第一行是車廂總數,第二行是個不同的數表示初始的車廂順序。
【輸出】
一個數據,是最少的旋轉次數。
【輸入樣例】
4
4 3 2 1
【輸出樣例】
6
【答案&程式碼】
顯然,題意說明,我們只能將相鄰的車廂位置交換,這顯然是氣泡排序的實現過程,所以這道題目,應該用氣泡排序來解決,程式碼如下。
#include<stdio.h>
void swap(int *a,int *b){/*交換a,b的值*/
int temp=*a;
*a=*b;
*b=temp;
return;
}
int main(void){
int n;
scanf("%d",&n);
int box[n];
for(int i=0; i<n;i++)
scanf("%d",&box[i]);
int sum=0;
for(int i=1;i<n;i++)
for(int j=0;j<i;j++)
if(box[i]<box[j]){
swap(&box[i],&box[j]);
sum+=1;/*每交換1次,交換次數加1*/
}
printf("%d",sum);
return 0;
}
T1311 : 求逆序對
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
給定一個序列,如果存在並且,那麼我們稱之為逆序對,求逆序對的數目。
【輸入】
第一行為,表示序列長度,接下來的行,第行表示序列中的第個數。
【輸出】
所有逆序對總數。
【輸入樣例】
4
3
2
3
2
【輸出樣例】
3
【提示】
。
【答案&程式碼】
通過理性分析,我們可以得出,用所有的排序演算法都可以完成本題,只需要統計每一個數所構成的逆序對個數即可,但是因為氣泡排序、插入排序等排序演算法時間複雜度為,快速排序不穩定,此題應選用歸併排序,程式碼如下。
#include<stdio.h>
int n,a[100001],c[100001];
unsigned long long ans=0;
void m(int l,int r){
int mid=(l+r)/2,i,j,tmp;
if(l>=r)
return;
m(l,mid);
m(mid+1,r);
tmp=l;
for(i=l,j=mid+1;i<=mid&&j<=r;)
if(a[i]>a[j])
c[tmp++]=a[j++],ans+=mid-i+1;
else c[tmp++]=a[i++];
if(i<=mid)
for(;i<=mid;)
c[tmp++]=a[i++];
if(j<=r)
for(;j<=r;)
c[tmp++]=a[j++];
for(i=l;i<=r;i++)
a[i]=c[i];
}
int main(void){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",a+i);
m(1,n);
printf("lld",ans);
return 0;
}
T1176 : 誰考了第k名
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
在一次考試中,每個學生的成績都不相同,現知道了每個學生的學號和成績,求考第名學生的學號和成績。
【輸入】
第一行有兩個整數,分別是學生的人數,和求第名學生的。
其後有行資料,每行包括一個學號(整數)和一個成績(浮點數),中間用一個空格分隔。
【輸出】
輸出第名學生的學號和成績,中間用空格分隔。(注:請用%g
輸出成績)
【輸入樣例】
5 3
90788001 67.8
90788002 90.3
90788003 61
90788004 68.4
90788005 73.9
【輸出樣例】
90788004 68.4
【答案&程式碼】
顯然,對於每個已知的學號,都有且只有個成績,所以我們可以使用結構體來解決這道題,結構體進行排序(運用<algorithm>
中的std::sort
函式)需要對<
運算子進行過載或運用自定義的比較函式,程式碼如下。
#include<stdio.h>
#include<algorithm>
struct st{
char id[16];
double gr;
};
bool cmp(st a,st b){
return a.gr>b.gr;
}
int main(void){
int n,k;
scanf("%d%d",&n,&k);
st stu[n];
for(int i=0;i<n;i++)
scanf("%s%lf",stu[i].id,&stu[i].gr);
std::sort(stu,stu+n,cmp);
printf("%s %g",stu[k-1].id,stu[k-1].gr);
return 0;
}
T1177 : 奇數單增序列
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
給定一個長度為(不大於)的正整數序列,請將其中的所有奇數取出,並按升序輸出。
【輸入】
第行為;
第行為個正整數,其間用空格間隔。
【輸出】
增序輸出的奇數序列,資料之間以逗號間隔。資料保證至少有一個奇數。
【輸入樣例】
10
1 3 2 6 5 4 9 8 7 10
【輸出樣例】
1,3,5,7,9
【答案&程式碼】
我們只需要在輸入的時候使用一些小技巧,將偶數去除,再將陣列排序輸出即可,程式碼如下。
#include<stdio.h>
#include<algorithm>
int main(void){
int n;
scanf("%d",&n);
int num[n];
for(int i=0;i<n;i++){
scanf("%d",&num[i]);
if(num[i]%2==0)
i--,n--;
}
std::sort(num,num+n);
printf("%d",num[0]);
for(int i=1;i<n;i++)
printf(",%d",num[i]);
return 0;
}
T1178 : 成績排序
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
給出班裡某門課程的成績單,請你按成績從高到低對成績單排序輸出,如果有相同分數則名字字典序小的在前。
【輸入】
第一行為,表示班裡的學生數目;
接下來的行,每行為每個學生的名字和他的成績,中間用單個空格隔開。名字只包含字母且長度不超過,成績為一個不大於的非負整數。
【輸出】
把成績單按分數從高到低的順序進行排序並輸出,每行包含名字和分數兩項,之間有一個空格。
【輸入樣例】
4
Kitty 80
Hanmeimei 90
Joey 92
Tim 28
【輸出樣例】
Joey 92
Hanmeimei 90
Kitty 80
Tim 28
【答案&程式碼】
思路與T1176
類似,程式碼如下。
#include<stdio.h>
#include<string.h>
#include<algorithm>
struct st{
char id[16];
int gr;
};
bool cmp(st a,st b){
if(a.gr==b.gr)
return strcmp(a.id,b.id)==-1;
else
return a.gr>b.gr;
}
int main(void){
int n;
scanf("%d",&n);
st stu[n];
for(int i=0;i<n;i++)
scanf("%s%d",stu[i].id,&stu[i].gr);
std::sort(stu,stu+n,cmp);
for(int i=0;i<n;i++)
printf("%s %d\n",stu[i].id,stu[i].gr);
return 0;
}
T1179 : 獎學金
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
某小學最近得到了一筆贊助,打算拿出其中一部分為學習成績優秀的前名學生髮獎學金。期末,每個學生都有門課的成績:語文、數學、英語。先按總分從高到低排序,如果兩個同學總分相同,再按語文成績從高到低排序,如果兩個同學總分和語文成績都相同,那麼規定學號小的同學排在前面,這樣,每個學生的排序是唯一確定的。
任務:先根據輸入的門課的成績計算總分,然後按上述規則排序,最後按排名順序輸出前五名學生的學號和總分。注意,在前名同學中,每個人的獎學金都不相同,因此,你必須嚴格按上述規則排序。例如,在某個正確答案中,如果前兩行的輸出資料(每行輸出兩個數:學號、總分)是:
7 279
5 279
這兩行資料的含義是:總分最高的兩個同學的學號依次是號、號。這兩名同學的總分都是(總分等於輸入的語文、數學、英語三科成績之和),但學號為的學生語文成績更高一些。如果你的前兩名的輸出資料是:
5 279
7 279
則按輸出錯誤處理,不能得分。
【輸入】
包含行:
第行為一個正整數(小於),表示該校參加評選的學生人數。
第到行,每行有個用空格隔開的數字,每個數字都在到之間。第行的個數字依次表示學號為的學生的語文、數學、英語的成績。每個學生的學號按照輸入順序編號為(恰好是輸入資料的行號減)。
【輸出】
共有行,每行是兩個用空格隔開的正整數,依次表示前名學生的學號和總分。
【輸入樣例1】
6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
【輸出樣例1】
6 265
4 264
3 258
2 244
1 237
【輸入樣例2】
8
80 89 89
88 98 78
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
【輸出樣例2】
8 265
2 264
6 264
1 258
5 258
【答案&程式碼】
程式碼如下。
#include<stdio.h>
#include<string.h>
#include<algorithm>
struct node{
int id,Ch,Ma,En;
};
bool cmp(node a,node b){
if(a.Ch+a.Ma+a.En==b.Ch+b.Ma+b.En)
if(a.Ch==b.Ch)
return a.id<b.id;
else
return a.Ch>b.Ch;
else
return a.Ch+a.Ma+a.En>b.Ch+b.Ma+b.En;
}
int main(void){
int n;
scanf("%d",&n);
node st[n];
for(int i=0;i<n;i++){
st[i].id=i+1;
scanf("%d %d %d",&st[i].Ch,&st[i].Ma,&st[i].En);
}
std::sort(st,st+n,cmp
相關推薦
資訊學奧賽一本通(C++版)第一部分 C++語言 第五章 陣列
第五章 陣列
第一節 一維陣列
T1102 : 與指定數字相同的數的個數
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
輸出一個整數序列中與指定數字相同的數的個數。
【輸入】
輸入包含三行:
第一行為N(N≤100)N
資訊學奧賽一本通(C++版)第一部分 C++語言 第四章 迴圈結構的程式設計
第四章 迴圈結構的程式設計
第一節 for語句
T1059 : 求平均年齡
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
班上有學生若干名,給出每名學生的年齡(整數),求班上所有學生的平均年齡,保留到小數點後兩位。
【輸入】
資訊學奧賽一本通(C++版) 第一部分 C++語言 第四章 迴圈結構的程式設計
//1091 求階乘的和#include <stdio.h>int f(int n){ int i,ans=1; for(i=1;i<=n;i++) ans*=i; return ans;}int main(){ int n,i,sum=0; sc
資訊學奧賽一本通(C++版)第一部分 C++語言 第三章 程式的控制結構
第三章 程式的控制結構
第一節 if選擇結構
T1039 : 判斷數正負
【題目描述】
給定一個整數NNN,判斷其正負。如果N>0N>0N>0,輸出positive;如果N=0N=0N=0,輸出zero;如果N<
資訊學奧賽一本通(C++版)
2018年資訊學奧賽NOIP資料下載 資訊學奧賽一本通(C++版) 第一部分 C++語言 第一章 C++語言入門
//1000 入門測試題目 #include <stdio.h> int main(){ int a,b; scanf("%d%d",&a,&b)
資訊學奧賽一本通(C++版)第二部分 基礎演算法 第一章 高精度計算
第一章 高精度計算
模板在最後。
T1307 : 高精度乘法
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
【輸入】
【輸出】
【輸入樣例】
【輸出樣例】
【答案&程式碼】
T1308 : 高精除
時間限制:
資訊學奧賽一本通(C++版) 第三部分 資料結構 第三章 樹
//1336 【例3-1】找樹根和孩子
//提交,未通過,明白了,孩子必須按字典序輸出
//修改,提交,AC 2017-12-13 18:54
//該題思路可以預計,與書中提供的程式碼很不相同,書中猜測用的是左子右兄表示法,日後驗證
//該題,本人思路,鄰接表,有向圖.
//很明顯,水平上了一個臺階。
#i
資訊學奧賽一本通(C++版) 第三部分 資料結構 第二章 佇列
//1334 【例2-3】圍圈報數//迴圈佇列,取模,數列空出一個空間//提交,未通過,執行超時//90分程式碼 #include <stdio.h>int q[10000];int main(){ int n,m,h,t,i,mod; scanf("%d%d",&n,&
資訊學奧賽一本通(C++版) 第二部分 基礎演算法 第八章 廣度優先搜尋算
//1329 【例8.2】細胞//編寫過程中,發現輸入資料用整數無法讀取,要採用字串形式//核心思路,將非零數字字元改成0字元 //將程式碼修改,提交AC #include <stdio.h>int n,m,next[][2]={{1,0},{-1,0},{0,1},{0,-1}};char a[
資訊學奧賽一本通(C++版) 第二部分 基礎演算法 第一章 高精度計算
//1307 【例1.3】高精度乘法
//手動模擬乘法運算
//提交,測試點5,答案錯誤,猜測,應該是0的情況,沒考慮
//提供一組測試資料
//輸入:
//123
//0
//輸出:
//0
//考慮了0的情況,修改,提交AC 2017-11-9
//編到這裡,感覺高精度加是高精度演算法的基礎
#inc
資訊學奧賽一本通(C++版) 第二部分 基礎演算法 第四章 遞迴演算法
//1206 放蘋果 遞迴 //1192 放蘋果//http://www.cnblogs.com/dongsheng/archive/2012/08/15/2640468.html此文介紹得不錯,摘抄如下://8 解題分析://9 設f(m,n) 為m個蘋果,n個盤子的放法數目,則先對n
資訊學奧賽一本通(C++版) 網站補充題目
//1414 【2017NOIP普及組】成績
//樣例通過,提交AC 2017-12-31 21:45
#include <stdio.h>
int main(){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
prin
資訊學奧賽一本通(C++版)第二部分 基礎演算法 第二章 資料排序
第二章 資料排序
T1310 : 車廂重組
時間限制: 1000 ms 記憶體限制: 65536 KB
【題目描述】
在一箇舊式的火車站旁邊有一座橋,其橋面可以繞河中心的橋墩水平旋轉。一個車站的職工發現橋的長度最多能容納兩節車廂,如果將橋旋轉180180
資訊學奧賽一本通(C++版) 第三部分 資料結構 第四章 圖論演算法
資訊學奧賽一本通(C++版) 第三部分 資料結構 第四章 圖論演算法
http://ybt.ssoier.cn:8088/
第一節 圖的遍歷
//1341 【例題】一筆畫問題
//在想,是輸出尤拉路,還是歐拉回路
//從哪點開始遍歷,
//點的資料範圍,邊的資料範圍
資訊學奧賽一本通演算法(C++版)基礎演算法:高精度計算 高精度加法(大位相加)
2018年資訊學奧賽NOIP資料下載
1 #include <bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 char a1[100],b1[100]; 6 int a[100],b[100],c[100];/
C++資訊學奧賽一本通題庫1032
大象喝水查
時間限制: 1000 ms 記憶體限制: 65536 KB
提交數: 1472 通過數: 969
【題目描述】
一隻大象口渴了,要喝20升水才能解渴,但現在只有一個深h釐米,底面半徑為r釐米的小圓桶(h和r都是整數)。問大象至少要喝
資訊學奧賽一本通 小球(drop)
2018年資訊學奧賽NOIP資料下載 This drop is gonna last forever!
許多的小球一個一個的從一棵滿二叉樹上掉下來組成FBT(Full Binary Tree,滿二叉樹),每一時間,一個正在下降的球第一個訪問的是非葉子節點。然後繼續下降時,或者走右子樹,或
(資訊學奧賽一本通 1299)糖果#線性動態規劃#
題意:給出n個數,找出若干個數,使它們的和為k的倍數,並輸出最大的數。狀態轉移方程:f[i][j]表示前i個數%k=j的總數。f[i][j]=max(f[i-1][j],f[i-1][tmp]+a[i]
C++資訊學奧賽一本通題庫1036A*B問題
A*B問題
時間限制: 1000 ms 記憶體限制: 65536 KB
提交數: 3404 通過數: 956
【題目描述】
輸入兩個正整數A和B,求A*B的值。注意乘積的範圍和資料型別的選擇。
【輸入】
一行,包含兩個正整數A和B,中間用單個空格隔
C++資訊學奧賽一本通題庫1034計算三角形面積
計算三角形面積
時間限制: 1000 ms 記憶體限制: 65536 KB
提交數: 1813 通過數: 622
【題目描述】
平面上有一個三角形,它的三個頂點座標分別為(x1, y1), (x2, y2), (x3, y3),那麼請問這個三角形的