各校歷年復試機試試題
清華、北大、華科試題詳細筆記部分,少筆記部分與少數leetcode【含個人整理筆記】
?
一、詳細筆記部分:
2018.3.4
[if !supportLists]1. [endif]求給出整數序列的最大序列和
//考點:動態規劃,貪心
//S(n) = O(n)
//1.如果sum小于零,sum從下一個位置開始求和
//2.int范圍:-2^31~2^31-1,maxSubSum與sum超出范圍使用long
#include
using namespace std;
void maxSubStr(int n, int s[]){
??? long sum = 0;
??? long maxSubSum = -99999999;
??? for(int i = 0; i < n;i++){
??????? sum = sum > 0 ? sum :0;
??????? sum += s[i];
??????? maxSubSum = sum >maxSubSum ? sum : maxSubSum;
??? }
???cout<
}
int main(){
??? int n;
??? while(cin>>n){
??????? int s[n];
??????? for(int i = 0; i < n;i++){
??????????? cin>>s[i];
??????? }
??????? maxSubStr(n, s);
??? }
??? return 0;
}
[if !supportLists]2. [endif]求AB兩地之間的最小花費(價格與距離有關聯)
//考點:dp(動態規劃),最短代價的問題
//S(n)=O(n * n)
//思路:1.使用ticket函數求出每兩地的距離相對應的價格(代價),如果小于L1代價為L1
//2.從A地初始化開始,從A地逐漸到B地;for循環條件是i從A+1開始到B
//3.使用j初試為i-2,在while中循環,循環條件是j>=A,而且兩地的距離必須在L3以內,否則退出循環
//4.cost[i] vs cost[j]:上述循環過程中如果A到此地的代價>A到上一地的代價與上一地和此地之間的和,則A到此地的代價被后者代替掉
//5.碎碎念: cost代表代價(代價)最優解,a代表輸入的原始路徑長度(從起始站A開始的距離)
//6.最終到達的終點B,cost[B]存儲A、B之間的最短花費
#include
using namespace std;
int L1, L2, L3, C1, C2, C3;
int A, B;//分別表示起始站和終點站
int N;//路線上的總的火車站數目
//計算兩地的票價(代價)
int ticket(int dis){
??? if(dis <= L1){
??????? return C1;
??? }else if(dis <= L2){
??????? return C2;
??? }else{
??????? return C3;
??? }
}
int main(){
???while(cin>>L1>>L2>>L3>>C1>>C2>>C3){
???????cin>>A>>B>>N;
??????? //前者表示第一站到達第i個站的原始路徑長度,后者表示到達當前地點的最短路徑長度
??????? int a[N], cost[N];
??????? for(int i = 2; i <= N;i++){
??????????? cin>>a[i];
??????? }
??????? //初始化第一個站臺的距離為0,A地沒有出發的代價為0
??????? a[1] = 0;
??????? cost[A] = 0;
??????? //開始計算最小的路徑
??????? //從序號為A的地點開始,達到B地點,逐次計算最小代價(花費)的方案
??????? for(int i = A + 1; i<= B; i++){
?????? ?????cost[i] = cost[i - 1] + ticket(a[i] - a[i- 1]);
??????????? int j = i - 2;
??????????? //循環條件:j從A地出發,兩地的距離一定要在L3之內(包括L3)
??????????? //動態規劃核心
??????????? while(j >= A&& (a[i] - a[j]) <= L3){
??????????????? if(cost[i] >cost[j] + ticket(a[i] - a[j])){
??????????????????? cost[i] =cost[j] + ticket(a[i] - a[j]);
??????????????? }
??????????????? j--;
??????????? }
??????? }
???????cout<
??? }
??? return 0;
}
[if !supportLists]3. [endif]求給出的0~1000的整數N的階乘
//考點:大數乘法
//S(n)= O(n*n)
//步驟思路:第一次碰到大數乘法的問題,思路可能比較固定,牢記~
//1.使用digit接收階乘的最終結果為一個個數組元素,長度設置為較長的10000個元素
//2.初始化digit[size++]=1,size初始為0,即digit[0]=1;
//3.外層循環使用i從2到n,外層循環中添加局部變量k=0,內層循環使用j從0到size-1,使用t接收(digit[j]*i+k)/10,
//digit[i]用(digit[j]*i+k)%10賦值
//4.該循環結束后只要k非零,就將digit[size]賦值為k%10,k/=10作為步長,其中size每循環一次就加一次
//5.下一次的while循環中的size從上一次while循環產生的最新size值到此次while循環條件k!=0的最大size
//6.最后從size-1到0依次輸出數組元素值
#include
using namespace std;
int main(){
??? int n;
??? while(cin>>n){
??????? int digit[10000];//接收階乘結果的一位位數字為數組元素
??????? int size = 0;
??????? digit[size++] = 1;
??????? for(int i = 2; i <= n; i++){
??????????? int k = 0;
??????????? for(int j = 0; j < size; j++){
??????????????? int t = (digit[j] * i + k) /10;
??????????????? digit[j] = (digit[j] * i + k) %10;
??????????????? k = t;
??????????? }
??????????? while(k != 0){
??????????????? digit[size++] = k % 10;
??????????????? k /= 10;
??????????? }
??????? }
??????? for(int i = size - 1; i >= 0; i--){
??????????? cout<
??????? }
??????? cout<
??? }
??? return 0;
}
2018.3.5
4.挖掉區間里面的樹,計算剩余樹木的總數
//考點:離散化,數組標記
//時間復雜度:O(L* M + L)
//思路:論壇看到一個算法,思路很清晰,在這里注解一下
//1.初始化數組mark(注意數組長度為N+1),每個數組值為1,表示沒被挖走;
//2.while循環M,每次減去1。在循環里面逐個將每一個在所給的區間里的樹(包括邊界)去掉,用數組mark標記
//3.從起始樹到結束樹(0~L,包括邊界),如果沒有標記就是剩下的樹的個數
#include
using namespace std;
int main(){
??? int L, M;//馬路長度為L,輸入M組整數,每組一對數字
??? int count = 0;//多少樹沒被挖走
??? while(cin>>L>>M){
??????? int mark[L + 1];//給每一顆樹做標記,是否被挖掉(移走^_^);注意,總共有N+1顆樹
??????? int from, to;
??????? //初始化M數組里面每個元素的值是1,表示沒被挖走
??????? for(int i = 0; i <= L; i++){
??????????? mark[i] = 1;
??????? }
??????? while(M > 0){//M一個個減,只要>0
??????????? cin>>from>>to;//在循環里面就不要用數組了,喜
??????????? for(int i = from; i <= to; i++){
??????????????? mark[i] = 0;//移走
??????????? }
??????????? M--;
??????? }
??????? for(int i = 0; i <= L; i++){//包括第L顆樹(從0開始)
???????????? if(mark[i] == 1){//沒被挖走
???????????????? count++;
???????????? }??
??????? }
??????? cout<
??? }
??? return 0;
}
5.大數乘法,將一個長度超過1000的數轉換成二進制,然后逆置零,后再由二進制轉換成十進制
//考點:大數乘法,十進制轉二進制,逆序數
//S()=O(n*n)
//思路:使用字符串類型的a接收1000位以內的大數,定義一個轉換函數conversion用于各個進制之間的轉換,
//通過調用兩次conversion(原進制,原數據,后進制),得到string a,后reverse(a.begin(),end())
//1.外層循環i從1~a.size(),接收余數t的k初始化為0。注意,使用size.()方法接收字符串的長度
//2.內層循環j從i開始到a.size(),因為要越過高位0
//3.內層循環中將(k * m + a[j] -'0') % n的值給t,a[j]=(k * m + a[j] - '0') / n + '0'(string型)
//4.k接收余數t
//5.在外層循環里將b用char(k +'0')依次連接
//6.外層循環的步長用i決定:a[i]=='0'則i++,即此次產生的是0(高位),則越過
#include
using namespace std;
string conversion(int m, string a, int n){
??? int k = 0;
??? string b;
??? int l = a.size();
??? for(int i = 0; i < l;){
??????? k = 0;
??????? for(int j = i; j < l;j++){//比如123/2得到061跳過高位0,繼續
??????????? int t = (k * m + a[j]- '0') % n;
??????????? a[j] = (k * m + a[j]- '0') / n + '0';
???? ???????k = t;
??????? }
??????? b += char(k + '0');
??????? while(a[i] == '0') i++;
??? }
??? return b;
}
int main(){
??? string a, b;
??? while(cin>>a){
??????? b = conversion(10, a,2);???????
??????? a = conversion(2, b, 10);
??????? reverse(a.begin(),a.end());
???????cout<
??? }
??? return 0;
}
6.搜索學生數
//考點:查詢
//S(n)=O(n)
//構造對象stu,Stu stu[1000]實例化對象成為一個數組
#include
using namespace std;
typedef struct{
??? int id;
??? char name[100];
??? char sex[20];
??? int age;
}Student;
int main(){
??? int i, j, n, m, flag, no;
??? Student stu[10000];
??? while(scanf("%d",&n)){
??????? for(int i = 0; i < n;i++){
???????????scanf("%d%s%s%d", &stu[i].id, stu[i].name, stu[i].sex,&stu[i].age);
??????? }
??????? cin>>m;
??????? for(i=0;i
??????????? flag=0;
??????????? cin>>no;
??????????? for(j=0;j
???????????????if(no==stu[j].id){
???????????????????cin>>stu[j].id>>stu[j].name>>stu[j].sex>>stu[j].age;
???????????????????cout<
?? ????????????????//printf("%d %s %s%d\n",stu[j].id,stu[j].name,stu[j].sex,stu[j].grade);
??????????????????? flag=1;
??????????????????? break;
??????????????? }
??????????? }
??????????? if(flag==0)
????????????????cout<<"No Answer!"<
??????? }
?? ?}
??? return 0;
}
2018.3.6
7.我要回家
//考察點:最短距離的一個變體
//N cities,M roads
//S()=O(max(n * n), N + m + n)
//思路及步驟:dijkstra算法,E對象包含兩個參數,time與next,
//內層循環中比較當前的總距離與行一次的距離和此次間隔的和的大小,取小的
//1.初始化:三次循環,置空N條邊(1~N),連接m條路(m>0),1~n mark置false、dis置-1以及接收leader的輸入
//2.1~n-1循環,內層循環為j從0至edge[newP].size(),分別賦值time和next
//3.continue的條件是leader[newP] = 2 &&leader[next]==2 || mark[next] = true
//4.仍在當前循環,如果dis[next] > dis[newP] + time,而且dis[next] = -21則將dis[newP] + time賦值給des[next]
//5.dis[j] = dis[j] + time條件是dis不為-1,
//6.在外層循環(i)接下來從1~n依次判斷若dis不是-1,mark為false,dis
//7.mark[newP]=true作為外層循環中的最后一步
//8.在外層循環中外,輸出結果dis[2]
#include
using namespace std;
#define N 601//city
#define M 10000//road
typedef struct{
??? int time;
??? int next;
}E;
vector edge[M];//roads
bool mark[N];
int dis[N];
int leader[N];
int main(){
??? int n, m;
??? while(scanf("%d",&n) != EOF && n != 0){
??????? scanf("%d",&m);
??????? int i, j, a, b, t;
??????? //清空N個城市
??????? for(i = 1; i <= N;i++){
??????????? edge[i].clear();
??????? }
??????? //連接m條路,放入屬性? //city
??????? while(m--){
???????????scanf("%d%d%d", &a, &b, &t);
??????????? E tmp;
??????????? tmp.time = t;
??????????? tmp.next = b;
???????????edge[a].push_back(tmp);
??????????? tmp.next = a;
???????????edge[b].push_back(tmp);
??????? }
??????? //初始化,不標記,距離為-1,接收輸入leader
??????? for(i = 1; i <= n;i++){
??????????? mark[i] = false;
??????????? dis[i] = -1;
??????????? scanf("%d",&leader[i]);
??????? }
??????? int time, next, newP;
??????? newP = 1;
??????? mark[1] = true;
??????? dis[1] = 0;
??????? //求解最優路徑
??????? for(i = 1; i < n;i++){//1~n-1
??????????? for(j = 0; j
??????????????? time =edge[newP][j].time;
??????????????? next =edge[newP][j].next;
??????????????? if(leader[newP]== 2 && leader[next] == 1 || mark[next] == true){
??????????????????? continue;
??????????????? }
??????????????? if(dis[next] ==-1 || dis[next] > dis[newP] + time){
??????????????????? dis[next] =dis[newP] + time;
??????????????? }
??????????? }
??????????? int min = 100200300;
??????????? for(j = 1; j <= n;j++){
??????????????? if(dis[j] != -1&& mark[j] != true && dis[j] < min){
??????????????????? newP = j;
???? ???????????????min = dis[j];
??????????????? }
??????????? }
??????????? mark[newP] = true;
??????? }
??????? printf("%d\n",dis[2]);
??? }
??? return 0;
}
8.誰是你潛在的朋友
//考點:遍歷,匹配
//S(n) = O(n * n)
//上層遍歷找到自己的朋友就加1,條件是i!=j且相同的書
//count[i]是第i+1個人的朋友數
#include
using namespace std;
int main(){
??? int n, m;
??? while(cin>>n>>m){
??????? int book[n];
??????? int i, j, count[n];
??????? for(i = 0; i < n;i++){
??????????? count[i] = 0;//默認沒朋友
??????? }
??????? for(i = 0; i < n;i++){
???????????cin>>book[i];//n個人所喜歡的書的編號
??????? }
??????? for(i = 0; i < n;i++){
??????????? for(j = 0; j < n;j++){
??????????????? if(book[i] ==book[j] && i != j){
??????????????????? count[i]++;
??????????????? }
??????????? }
??????? }
??????? for(i = 0; i < n;i++){
??????????? if(count[i] == 0){
???????????????cout<<"BeiJu"<
??????????? }else{
???????????????cout<
??????????? }
??????? }
??? }
??? return 0;
}
9..將一個不超過三十位的十進制數轉換為二進制數
//考點:大數進制轉換
//S(n)=O(n * n)
//思路:大數類型轉換的題型,很經典。
//1.char str接收輸入的不超過30位的十進制非負整數。注意,strlen(char類型)接收char類型數組長度
//2.用get數組分別獲得一位位數,組成int類型的數組
//3.while(index < l),從index 0到strlen(l) - 1,內層循環在i到l-1,逐位取(get[i]+temp*10)/2為div,即商;
//4.(get[i]+temp*10)%2為num,后get[i]接收div;
//5.余數非0則temp置1,否則為0
//6.內層循環結束后,temp置0,如果get[index]=0,則index++;
//7.接下來將ans[j]接收num,后j++
//8.while循環完畢后,j-1~0,依次輸出ans[i]
//9.若有多組數據則換行
#include
using namespace std;
int main(){
??? int ans[1000], get[100];
??? char str[100];
??? int i, j, l, div, num, temp;
??? l = strlen(str);
??? j = 0, temp = 0;
??? while(scanf("%s",str) != EOF){
??????? l = strlen(str);//取字符串長度
??????? for(i = 0; i < l;i++){
??????????? get[i] = str[i] -'0';
??????? }
??????? int index = 0;
??????? while(index < l){
??????????? for(i = 0; i < l;i++){
??????????????? div = (get[i] +temp * 10) / 2;
??????????????? num = (get[i] +temp * 10) % 2;
??????????????? get[i] = div;//接收商
??????????????? if(num != 0){
??????????????????? temp = 1;
??????????????? }else{
??????????????????? temp = 0;
??????????????? }
??????????? }
??????????? temp = 0;
??????????? if(get[index] == 0){
??????????????? index += 1;
??????????? }
??????????? ans[j] = num;
??????????? j++;
??????? }
??????? for(i = j - 1; i >= 0;i--){
???????????printf("%d", ans[i]);
??????? }
??????? printf("\n");
??? }
??? return 0;
}
2018.3.7
10.W’s cipher
//考點:W氏密碼,多數組,二維數組
//時間復雜度S(n)=O(n), n為輸入的數組長度
//思路步驟:1.使用str1、str2、str3分別接收三種不同類型的數組,它們的索引號分別使用site1、site2、site3三個數組存儲
//2.初始re作為結果接收的數組,以上三個數組的大小均為MAX_VAL,不放宏定義為1000
//3.從鍵盤接收三個不全為零的整數k1、k2、k3
//4.輸入等待加密的字符串str;
//5.在a~i, j~r, s~z三種類型中對str串進行分類,記錄對應字符和字符的位置
//6.完畢后i置0,接收re[site1[(i + k1) % count1]] = str1[i]; i++
//7.重復str2, str3分別對re的賦值
//8.0~count-1,輸入結果數組re
#include
using namespace std;
#define MAX_VAL 1000
int main(int argc, char** agrgv){//char類型
??? string str;
??? int k1, k2, k3;
???while(cin>>k1>>k2>>k3 && (k1 != 0 || k2 != 0|| k3 != 0)){//從鍵盤接受輸入三個不全為零的數
??????? int i = 0, count = 0,count1 = 0, count2 = 0, count3 = 0;
??????? int site1[MAX_VAL],site2[MAX_VAL], site3[MAX_VAL];//接收索引序號
??????? char str1[MAX_VAL],str2[MAX_VAL], str3[MAX_VAL];//接收每個char字符
??????? char re[MAX_VAL];//結果字符數組
??????? if(cin>>str){
??????????? count =str.length();//求字符串長度
??????????? //一次接收讀入的字符與位置到相應的存儲數組
??????????? while(i < count){
??????????????? if(str[i] >='a' && str[i] <= 'i'){
??????????????????? str1[count1]= str[i];
??????????????????? site1[count1]= i;
??????????????????? count1++;
??????????????? }else if(str[i]>= 'j' && str[i] <= 'r'){
??????????????????? str2[count2]= str[i];
??????????????????? site2[count2]= i;
??????????????????? count2++;
??????????????? }else if(str[i]>= 's' && str[i] <= 'z' || str[i] == '_'){
??????????????????? str3[count3]= str[i];
??????????????????? site3[count3]= i;
??????????????????? count3++;
??????????????? }
??????????????? i++;
??????????? }
??????????? i = 0;
??????????? while(i < count1){
??????????????? re[site1[(i + k1)% count1]] = str1[i];
??????????????? i++;
??????????? }
??????????? i = 0;
??????????? while(i < count2){
??????????????? re[site2[(i + k2)% count2]] = str2[i];
??????????????? i++;
??????????? }
??????????? i = 0;
??????????? while(i < count3){
???????? ???????re[site3[(i + k3) % count3]] = str3[i];
??????????????? i++;
??????????? }
??????????? for(i = 0;? i < count; i++){
???????????????cout<
??????????? }
??????????? cout<
??????? }
??? }
??? return 0;
}
11.日志排序
//考點:排序
//S(n)取決于sort方法,比如如果是冒泡排序則是S(n) = O(n * n)
//思路:1.定義一個對象,三個屬性s,start,time分別表示整條記錄的字符串、開始時間以及持續時間
//2.定義持續時間time為double類,size作為總記錄條數進行初始化為0
//3.接收輸入:gets[r[size].s],并且需要r[size].s的長度(strlen())不為0
//4.sscanf函數!sscanf(r[size].s,"%s%s%lf", start1, start2, &r[size].time),分別以空格區分
//5.將start拼接,通過cmp排序———sort(r, r+size, cmp),時間短的置前(如果時間相同那么就將發生早的置前)
//6.0~size-1輸出r[i].s即為每條記錄的所有信息
#include
using namespace std;
struct Record{
??? char s[100];
??? string name;//用不到但是是屬性,得寫啊
??? string start;
??? double time;
}r[10000];
bool cmp(Record a, Record b){
??? if(a.time != b.time){
??????? return a.time
??? }else{
??????? return a.start
??? }
}
int main(){
??? int size = 0;
??? double time;
??? char start1[15], start2[15],name[15];
??? while(gets(r[size].s)&& strlen(r[size].s) != 0){
??????? sscanf(r[size].s,"%s%s%s%lf", name, start1, start2, &r[size].time);
??????? r[size++].start =string(start1) + string(start2);
??? }
??? sort(r, r + size, cmp);
??? for(int i = 0; i < size;i++){
???????cout<
??? }
??? return 0;
}
12.密碼翻譯
//考點:明文加密
//S(n)=O(n)
//char數組接收輸入的字符串,逐次加密
#include
usingnamespace std;
charencrypt(char c){
??? char res = x;//初始化
??? if(c == 'z'){
??????? res = 'a';
??? }else if(c == 'Z'){
??????? res = 'A';???????
??? }else if((c >= 'a' && c <='y') || (c >= 'A' && c <= 'Y')){
???????? res = c + 1;
??? }
??? return res;
}
intmain(){
??? char str[80];
??? while(gets(str)){
??????? for(int i = 0; i < strlen(str);i++){//strlen(str)求數組串長度
??????????? cout<
??????? }
??????? cout<
??? }
??? return 0;
}
2018.3.8
13.是否為樹
//考點:是否是樹的問題
//S(N) =O(N), N為預估可以接收的最大結點數
//思路:將一個個數對連接成圖,找到根結點,從根結點往下產看如果出現非樹的特征則返回false
//步驟:1.k在while(true)循環中初始為1,全局變量mark[N], ans標記是否為樹,n表示結點數, root表示是根結點數目
//2.mark[N]初始化為-1,0表示結點出現過,1表示入度數
//3.循環接收x,y數對的輸入,如果均為零則退出本場對樹的判斷
//4.如果均為-1,則退出程序執行
//5.若mark[x]==-1,則賦值為0;若mark[y]==-1,則賦值為1,否則(y出現過)則mark[y]+1,即入度加1;至此,接收輸入結束
//6.開始逐漸檢查各個結點:如果mark不是-1,則n++;
//7.如果mark>1,那么不是樹,break此次循環, 否則如果mark為0,則假定是樹根,之后判斷是否root>1,若是則不是樹,break
//8.討論合計情況:如果root是0,則不是樹;如果n是0則是空樹
//9.ans標記如果是true則是樹,否則不是
//10.別忘了k最后要k++, 在最外層循環中
#include
usingnamespace std;
#defineN 10001//那就多開一點空間吧
intmark[N];//0表示出現過,1表示入度為1, -1表示沒有出底線過
intmain(){
??? int k = 1;//case編號
??? int x, y;
??? while(true){
??????? bool ans = true;//假定是樹
??????? int root, i, n;//,root表示入度為零的節點數,i計數用,n表示結點個數
??????? root = 0, n = 0;//假設為入度為零的結點數,注意一顆空樹一定要有root!=0,但是可以有節點數n為零
??????? for(i = 0; i < N; i++){
??????????? mark[i] = -1;//假定所有的標記都是-1,即沒有出現過
??????? }
??????? while(scanf("%d %d", &x,&y) != EOF){
??????????? if(x == 0 && y == 0){//本次數對結束,退出while循環
??????????????? break;
??????????? }else if(x == -1 && y ==-1){
? ??????????????return 0;//退出程序的標志
??????????? }
??????????? if(mark[x] == -1){//i之前沒有出現過
??????????????? mark[x] = 0;//現在出現了
??????????? }
??????????? if(mark[y] == -1){//j之前沒有出現
??????????????? mark[y] = 1;//j作為入度
??????????? }else{//如果以前出現過b的話,那么現在b的入度要加1
??????????????? mark[y]++;
??????????? }
??????? }
??????? //逐次檢查各個節點的情況
??????? for(i = 0; i < N; i++){
??????????? if(mark[i] != -1){//統計一共的結點個數n
??????????????? n++;
??????????? }
??????????? if(mark[i] > 1){//入度大于一就不是樹
??????????????? ans = false;
??????????????? break;
??????????? }else if(mark[i] == 0){//懷疑他是根節點
??????????????? root++;
??????????????? if(root > 1){//又一次判斷不是樹的條件
??????????????????? ans = false;
??????????????????? break;
??????????????? }
??????????? }
??????? }//各個結點檢查結束
??????? //討論合計情況
??????? if(root == 0){
??????????? ans = false;
??????? }
??????? if(n == 0){//空樹的條件
??????????? ans = true;
??????? }
??????? if(ans){
??????????? printf("Case %d is atree.\n", k);//輸出的時候不需要的&
??????? }else{
??????????? printf("Case %d is not atree.\n", k);
??????? }
??????? k++;
??? }
??? return 0;
}
14.最簡的真分數的個數
//考點:最簡真分數,主要是求解gcd(遞歸),即是最大公約數的求法
//S(n)=O(n * n)
//思路:是不是最簡, 還有假分數呢? 判斷用歐幾里得的最大公約數求法
//步驟: 1.s[n]用來接收鍵盤輸入的一串數字
//2.0~n-1雙層循環,如果相等自然不是最簡真分數(值為1),內層循環continue;
//3.如果外層循環計數i對應的是s[i]>內層循環計數j對應的s[j],并且他們的最大公約數是1(即為最簡真分數),則最簡真分數的計數+1
//4.注意,最簡真分數的判斷需要用到歐幾里得算法gcd(a, b):b==0則返回a,否則遞歸返回gcd(b, a % b0)【注意牢記】
//5.輸出此次結果后換行
#include
usingnamespace std;
int n;
//歐幾里得算法求兩個數的最大公約數
intgcd(int a, int b){
??? if(b == 0){
??????? return a;
??? }else{
??????? return gcd(b, a % b);
??? }
}
intmain(){
??? while(cin>>n){
??????? int i, j, s[n], count;
??????? count = 0;//記錄最簡真分數的對數
??????? for(i = 0; i < n; i++){
??????????? cin>>s[i];
??????? }
??????? for(i = 0; i < n; i++){
??????????? for(j = 0; j < n; j++){
??????????????? if(s[i] == s[j]){
??????????????????? continue;//不是最簡真分數
??????????????? } else if(s[i] > s[j]&& gcd(s[i], s[j]) == 1){
??????????????????? count++;
??????????????? }
??? ????????}
??????? }
??????? cout<
??? }
??? return 0;
}
15.求中位數
//考點:求中位數
//S(n)=O(n* n)//如果sort()的時間復雜度為n * n, n,n為輸入的數據個數
//思路:1.接受輸入,從小到大排序(使用系統函數sort)
//2.sort(s,s+n, cmp),其中n為整數數組的長度, cmp注明升序/降序,省略cmp則默認升序
//2.根據數據總數的奇偶性選出中位數,如果是偶數則取平均數((a+b)/2即為向下取整)
#include
usingnamespace std;
boolcmp(int a, int b){
??? return a < b;
}
intmain(){
??? int n;
??? while(cin>>n){
??????? int s[n];
??????? int i, res;
??????? for(i = 0; i < n; i++){
??????????? cin>>s[i];
??????? }
??????? sort(s, s + n);//系統函數
??????? if(n % 2 == 0){//偶數
??????????? res = (s[n / 2] + s[n / 2 - 1]) /2;
??????? }else{
??????????? res = s[n / 2];
??????? }
??????? cout<
??? }
??? return 0;
}
16.小白鼠排隊
//考點:對象比較的問題
//S(n)=O(n*n),如果是冒泡排序的話
//思路:定義一個包含顏色和重量的小白鼠struct類型,排序,輸出重量從大到小的小白鼠的顏色
#include
usingnamespace std;
structMouse{
??? int weight;
??? string color;
}s[100];
boolcmp(Mouse a, Mouse b){
??? return a.weight > b.weight;
}
intmain(){
??? int n;
??? while(cin>>n){
??????? for(int i = 0; i < n; i++){
???????????cin>>s[i].weight>>s[i].color;
??????? }
??????? sort(s, s + n, cmp);
??????? for(int i = 0; i < n; i++){
??????????? cout<
??????? }
??? }
??? return 0;
}
17.分糖果
//題目:分糖果,老師每吹一次口哨小朋友就分給右手邊的小朋友一個糖果
//S(n)取決于每個人的糖果數
//如果分完后小朋友手中的糖果數為奇數,則老師添加一顆給他。
//求出每個小朋友有著相同的糖果數的時候老師共吹了幾多少次口哨,以及最后每個人擁有多少糖果
//考點:循環,考慮初始狀態(如果初始時糖果數為奇數不會另外獲得一顆糖果)
//步驟:1.定義每人擁有相同的糖果數標記con = 0,接收輸入n個小朋友,如果只有一個那就是不用吹口哨,最終這個小朋友手里有aa(第二個輸入)顆糖
//2.否則0~n逐次將第i個小朋友所有的糖果數放入num[i](初始定義num[10000]),rounds表示吹口哨的次數
//3.只要!con就循環,定義x接收為最后一個小朋友的糖果數num[n- 1],老師吹口哨,游戲開始
//4.從n - 1到1,第i個小朋友增加了第i-1個小朋友糖果數的一半
//5.第i-1個小朋友少了自己的一半的糖果數
//6.如果i不等于n-1并且第i個小朋友的糖果數和1按位與,那么num[i]++
//7.結束內層j循環,num[0]增加x/2,num[n-1]減去x/2
//8.如果num[0]&1,num[0]++,之后num[n - 1]&1,那么num[n - 1]++然后con=1
//9.從0到n-1,定義p =num[0],如果num[i]不等于p,則con置0,,并退出當前循環
//10.最后輸出rounds為口哨數,num[0]為最終每個小朋友擁有的糖果數
//注意:看不懂英文題目多讀幾遍
#include
usingnamespace std;
intmain(){
??? int n;//n個小朋友
??? while(scanf("%d", &n) !=EOF){//& n
??????? int con, rounds, num[10000];
??????? con = 0, rounds = 0;
??????? if(n == 1){//只有一個人好辦
??????????? int aa;
??????????? scanf("%d", &aa);
??????????? printf("0 %d\n", aa);
??????????? break;
??????? }
??????? for(int i = 0; i < n; i++){//每個小朋友的糖果數
??????????? scanf("%d", &num[i]);
??????? }
??????? while(!con){
??????????? int x = num[n - 1];
??????????? rounds++;
??????????? for(int i = n - 1; i >= 1; i--){
??????????????? num[i] += num[i - 1] / 2;
??????????????? num[i - 1] -= num[i - 1] / 2;
??????????????? if(i != n - 1 && num[i]& 1){
??????????????????? num[i]++;
??????????????? }
??????????? }
??????????? num[0] += x / 2;
??????????? num[n - 1] -= x / 2;
??????????? if(num[0] & 1){
??????????? ????num[0]++;
??????????? }
??????????? if(num[n - 1] & 1){
??????????????? num[n - 1]++;
??????????? }
??????????? con = 1;
??????????? for(int i = 0; i < n; i++){
??????????????? int p = num[0];
??????????????? if(num[i] != p){
??????????????????? con = 0;
??????????????????? break;
??????????????? }
??????????? }
??????? }
??????? printf("%d %d\n", rounds,num[0]);
??? }
??? return 0;
}
2018.3.9
18.八皇后問題
?//考點:象棋,八皇后;知識點:遞歸
//S(n) =O(n!),遞歸
//思路:定義二維數組為92種解法的存儲位置,根據題意選擇適當的解
//步驟:1.初始化全局變量a[95][10],c[10],total置0;深度優先遍歷棋盤,定義函數dfs(cur),cur表示從cur行開始檢測通路
//2.0~7進行i循環,根據題意選擇其實行對應的解——8位整數串
//3.詳細dfs定義:如果cur為8,則total+1,0~7遍歷a[total][i]=c[i]
//4.否則0~7循環,c[cur]接收索引i,初始ok為1,內層循環j從0~cur - 1,ok置0并退出內層循環的條件是c[j]== i或cur - i == j - c[j]或cur +i ==c[j] + j。
//5.內層循環結束后如果ok那遞歸調用dfs(cur + 1)
#include
usingnamespace std;
inta[95][10];//解
intc[10];
inttotal = 0;
//深度優先遍歷
voiddfs(int cur){//起始位置
??? if(cur == 8){
??????? total++;
??????? for(int i = 0; i < 8; i++){
???????? ???a[total][i] = c[i];
??????? }
??? }else{
??????? for(int i = 0; i < 8; i++){
??????????? c[cur] = i;//標記位置
??????????? int ok = 1;//默認是所求的解
??????????? for(int j = 0; j < cur; j++){
??????????????? if(c[j] == i || cur - i == j -c[j] || cur + i == c[j] + j){
??????????????????? ok = 0;
??????????????????? break;//此方案行不通啊
??????????????? }
??????????? }
??????????? if(ok){//i循環中此路可行
??????????????? dfs(cur + 1);//檢測下一行
??????????? }
??????? }
??? }
}
intmain(){
??? int N;
??? while(scanf("%d", &N) !=EOF){
??????? dfs(0);//從索引號0開始逐行檢測是否有通路
??????? for(int i = 0; i < 8; i++){//8皇后
??????????? printf("%d", a[N][i] +1);//根據需要取方案
??????? }
??????? //cout<
??????? printf("\n");
??? }
??? return 0;
}
19.大整數因子
//考點:大數求因子
//S()=O()
//思路:用string接收30位以內的整數,寫一個函數mod求解余數
//步驟:1.定義flag默認有因子,接收大整數
//2.0~9循環作為除數逐次檢測每一位數,循環索引為k
//3.mod函數逐次求出每一位數的余(d=(d*10+(s[i]-'0'))%k),返回余數d
//4.main中k循環里面,如果mod返回的是0,說明能被整除,則意味著找到因子k;
//5.如果flag是1,即標記為有因子,則打印空格,否則置1;輸出因子k
//6.k循環結束后判斷如果flag為0,說明沒有一個因子,則輸出none;此輪判斷結束,換行
#include
usingnamespace std;
//求余
intmod(string s, int k){
??? int d = 0;
??? for(int i = 0; i < s.size(); i++){//字符串長度
??????? d = (d * 10 + (s[i] - '0')) % k;
??? }
??? return d;//返回余數
}
intmain(){
??? string s;
??? while(cin>>s &&? s != "-1"){
??????? int flag = 0;//默認沒因子
??????? for(int k = 2; k <= 9; k++){
??????????? if(!mod(s, k)){//整除
??????????????? if(flag){
??????????????????? printf(" ");
??????????????? }else{
??????????????????? flag = 1;
??????????????? }
??????????????? printf("%d", k);
??????????? }
??????? }
??????? if(!flag){
??????????? printf("none");
??????? }
??????? cout<
??? }
??? return 0;
}
20.最小生成樹
//考點:最小生成樹,本題使用Kruskal方法,適用于邊少(點多)的情況
//S(n)=O(e*loge),e為邊數;prim算法時間復雜度為O(n * n),n為頂點個數,適用于點少(邊多)的情況
//思路:思路就很簡單了,分兩個集合V1、V2,V1初始為空集, V2存放樹中所有頂點,
//逐次將V2中最小邊的兩個端點放入V1,且要求V1中的點構成的圖無環,
//終止條件是V2空
//步驟:1.輸入定點數n,逐對接收頂點信息并以pair方式放入vector v中
//2.進入MST函數:v其實賦給了v2,v1為空集,定義res為最小生成樹的總長度,返回浮點類型
//3.MST內外層循環終止條件是v2.size()不大于0,循環中r,it,jt分別記錄單次選取的最短邊長度,及其對應的兩個定點序號
//4.0~v1.size()-1循環,其內0~v2.size()-1循環,記錄最短邊的條件是r==0或dist(v1[i],v2[j])
//5.i循環完成后v1增加v2[jt]這個點,v2中抹掉jt:v2.ersae(v2.begin()+jt), res增加r
//6.v2為空后返回res
//7.dist函數返回兩點之間距離
//8.main函數中輸出MST的返回值res
#include
usingnamespace std;
//求距離
floatdist(pair p1, pair p2){//pair數對
??? return sqrt((p1.first - p2.first) *(p1.first - p2.first) + (p1.second - p2.second) * (p1.second - p2.second));
}
//Kruskal
floatMST(vector> &v){//返回浮點數
??? vector> v1,v2(v);
??? float res;//最小生成樹的長度
??? while(v2.size() > 0){
??????? float r = 0, it = 0, jt = 0;
??????? for(int i = 0; i < v1.size(); i++){
??????????? for(int j = 0; j < v2.size();j++){
??????????????? if(r == 0 || dist(v1[i], v2[j])< r){//選短邊
??????????????????? r = dist(v1[i], v2[j]);
??????????????????? it = i;
??????????????????? jt = j;//記錄選中邊的頂點
??????????????? }
??????????? }
??????? }
??????? v1.push_back(v2[jt]);//v2中的點放入v1
??????? v2.erase(v2.begin() + jt);//抹掉指定點
??????? res += r;
??? }
??? return res;
}
intmain(){
??? int n;
??? while(cin>>n){
??????? float x, y;
??????? vector>v;
??????? for(int i = 0; i< n; i++){
??????????? cin>>x>>y;
??????????? v.push_back(pair(x, y));//逐次接收每個點
??????? }
??????? cout<
??? }
??? return 0;
}
21.放蘋果
//考點:第二類stirling數,即放球問題(允許空盒),遞歸求解
//S(n)=O(pow(m,n)),m個蘋果,n個盤子
//思路:遞推求解
//步驟:1.方案數函數:沒有蘋果或一個盤子只有一種情況,
//2.蘋果數<盤子數則盤子數用蘋果數更新,否則返回solve(m, n-1)+solve(m-n, n-1)
//3.在main中接收蘋果數和盤子數,根據solve函數輸出方案數
#include
usingnamespace std;
intsolve(int m, int n){
??? if(m == 0){
??????? return 1;
??? }
??? if(n == 1){
??????? return 1;//只有一個盤子
??? }
??? if(m < n){
??????? return solve(m, m);
??? }else{
??????? return solve(m, n - 1) + solve(m - n,n);//一般情況的遞歸
??? }
}
intmain(){
??? int m, n;
??? while(cin>>m>>n){
??????? cout<
??? }
??? return 0;
}
22.大數進制轉換
//考點:大數進制轉換
//S(n)=O(n* n),n為輸入整數的位數
//思路:逆序存儲待轉換數,i標記最高位,雙層循環取余數放入data數組中,
//最高位為零時外層循環的i才會減1。雙層循環結束后從高到低輸出結果
//步驟:1.gets(s)接收不超過30位數的整數,只要索引i<整數位數strlen(s),就逐次逆序存儲數字至d[]中
//2.i從strlen(s)-1至0作為外層循環(此處并非逐次i--),k初始化為0,內層循環j從i到0依次逐減
//3.循環中為t賦值為(d[j] + 10 * k) % 2,即取余,d[j] = (d[j] + 10 * k) / 2,即取商,k= t;【牢記經典步驟】
//4.data[low++]賦值為k, 如果此時d[i]為0則i--
//5.雙層循環結束,從low-1~0逐個輸出data[i];換行END
#include
usingnamespace std;
intmain(){
??? char s[50];
??? int d[150], data[150];
??? int i, j, k, low, t;
??? while(gets(s)){
??????? int length = strlen(s);
??????? i = 0;
??????? low = 0;
??????? while(i < length){
??????????? d[length - 1 - i] = s[i] - '0';
??????????? i++;
??????? }
??????? for(i = length - 1; i >= 0;){//i標記最高位,注意i--在最后
??????????? k = 0;
??????????? for(j = i; j >= 0; j--){
??????????????? t = (d[j] + 10 * k) % 2;
??????????????? d[j] = (d[j] + 10 * k) / 2;
??????????????? k = t;?
??????????? }
??????????? data[low++] = k;
??????????? if(d[i] == 0){
??????????????? i--;
??????????? }
??????? }
??????? for(i = low - 1; i >= 0; i--){
??????????? printf("%d", data[i]);
??????? }
??????? printf("\n");
??? }
??? return 0;
}
23.全排列
//考點:全排列
//S(n)=O(n!),有n!種序列
//借鑒了很多同學的算法,驚喜的發現python和C++都有全排列的內置函數!強大的next_permutation
//思路:輸入待求解串,排序sort(s.begin(), s.end()),
//do-while循環:只要next_permutation(s.begin(), s.end()),就輸出一種排列s,注意換行;循環結束后換行END
#include
usingnamespace std;
int main(){
??? string s;
??? while(cin>>s){
??????? sort(s.begin(), s.end());
??????? do{
??????????? cout<
??????? }while(next_permutation(s.begin(),s.end()));
??????? cout<
??? }
??? return 0;
}
?
?
?
二、少筆記部分:
1.整數轉八進制輸出
#include
using namespace std;
void change(int n){
???if(n == 0){
??????? return;
???}else{
??????? change(n / 8);
??????? cout<<(n % 8);
???}
}
int main(){
???int n;
???while(cin>>n){
??????? change(n);
???}
???return 0;
}
[if !supportLists]2. [endif]n階上樓問題(非遞歸)
#include
usingnamespacestd;
intfabonacci(intn){
????intcurrent = 1, oneback =
1, twoback = 1;
????for(inti = 1; i < n; i++){
????????twoback
= oneback;
????????oneback
= current;
????????current
= oneback + twoback;
????}
????returncurrent;
}
intmain(){
????intn;
????while(cin>>n){
????????cout<
????}
????return0;
}
[if !supportLists]3.??? [endif]a+b
#include
usingnamespacestd;
intmain(){
????inta, b;
????while(cin>>a){
????????cin>>b;
????????cout<
????}
????return0;
}
[if !supportLists]4. [endif]判斷是否為回文串
#include
usingnamespacestd;
voidjudge(string s){
????boolflag = true;
????for(inti = 0; i < s.size() /
2; i++){
???????if(s[i]
!= s[s.size() - 1 - i]){
????????????flag
= false;
????????????break;
???????}
????}
????if(flag){
????????cout<<"Yes!";
????}else{
????????cout<<"No!";
????}
????return;
}
intmain(){
????string s;
????while(cin>>s){
????????judge(s);
????????cout<
????}
????return0;
}
[if !supportLists]5.??? [endif]找出給定字符串中有重復的字符及其位置
#include
#include
usingnamespacestd;
voidfind(string s){
????inti, j;
????for(i = 0; i
< s.size() - 1; i++){
????????boolrepeat = false;//每次重置為不重復
????????if(s[i]
== '*'){
????????????continue;
????????}
????????for(j
= i + 1; j < s.size(); j++){
????????????if(s[i]
== s[j]){
????????????????if(!repeat){
????????????????????cout<
????????????????????repeat
= true;
????????????????}
????????????????cout<<","<
????????????????s[j]
= '*';
????????????}
????????}
????????if(repeat){
????????????cout<
????????}
????}
????return;
}
intmain(){
????string s;
????while(cin>>s){
????????find(s);
????}
????return0;
}
[if !supportLists]6. [endif]求y1=1! + 3! + ... + m!,y2 = 2! + 4! +... + p!(m,n分別為小于或等于給定n的最大奇數和偶數)
#include
#include
using namespace std;
int factorial(int n){
???if(n == 1){
??????? return 1;
???}else{
??????? return factorial(n - 1) * n;
???}
}
int main(){
???int n, i, j, y1, y2;
???y1 = 0, y2 = 0;
???while(cin>>n){
??????? for(i = 1; i <= n; i = i + 2){
?????????? y1 += factorial(i);
??????? }
??????? for(j = 2; j <= n; j = j + 2){
?????????? y2 += factorial(j);
??????? }
??????? cout<
???}
???return 0;
}
[if !supportLists]7.??? [endif]成績排序
//考點:對象,排序
//題目:輸入n為總人數,0表示降序,1表示升序,求按成績排序后的學生信息
#include
#include
#include
#include
usingnamespacestd;
structStudent{
????string name;
????intgrade;
};
booldesc(Student a, Student
b){
????returna.grade > b.grade;
}
boolasc(Student a, Student
b){
????returna.grade < b.grade;
}
intmain(){
????intn, order;
????vector
stu;
????while(cin>>n){
????????stu.resize(n);
????????cin>>order;
????????for(inti = 0; i < n; i++){
????????????cin>>stu[i].name>>stu[i].grade;
????????}
????????if(order
== 0){
????????????stable_sort(stu.begin(),
stu.end(), desc);
????????}else{
????????????stable_sort(stu.begin(),
stu.end(), asc);
????????}
????????for(inti = 0; i < n; i++){
????????????cout<
"<
????????}
????}
????return0;
}
[if !supportLists]8.??? [endif]約數個數
//題目:n個數,以后n行是n個數(1~10^9),分別換行輸出約數個數
#include
using namespace std;
int count(int n){
???int c = 0;
???if(n == 1){
??????? return 1;
???}else{
??????? int i;
??????? for(i = 1; i * i < n; i++){
??????????? if(n % i == 0){
??????????????? c = c + 2;
??????????? }
??????? }
??????? if(i * i == n){
??????????? c++;
??????? }
??????? return c;
???}
}
int main(){
???int num;
???while(cin>>num){
??????? int s[num];
??????? for(int i = 0; i < num; i++){
??????????? cin>>s[i];
???????????cout<
??????? }
???}
???return 0;
}
[if !supportLists]9.??? [endif]代理服務器個數
//n個服務器被m個代理服務器訪問,系統同一時刻只能使用一個代理服務器,求代理服務器切換的最少次數
#include
#include
usingnamespacestd;
intsolve(charp[100][16], intn, chars[500][16],
intm){
????inti, j;
????intmax = -1;
????for(i = 0; i
< n; i++){
????????for(j
= 0; j < m; j++){
if(!strcmp(s[j],p[i])){//相等
????????????????if(max
< j){
????????????????????max
= j;
????????????????}
????????????????break;
????????????}
????????}
????????if(j
== m){
????????????return0;//不用切換
????????}
????}
if(n == 1&& max != -1){//max沒有參加最長匹配
????????return-1;//無法完成
????}
????return1 + solve(p, n, s + max,
m - max);
}
intmain(){
????inti, n, m;
????while(cin>>n){
????????charp[n][16];
????????for(i
= 0; i < n; i++){
????????????cin>>p[i];
????????}
????????cin>>m;
????????chars[m][16];
????????for(i
= 0; i < m; i++){
????????????cin>>s[i];
????????}
????????cout<
n, s, m);
????}
????return0;
}
[if !supportLists]10.?? [endif]反序輸出
//將任意字符串反序輸出。ps:強大的C++有內置函數reverse啊
#include
#include
usingnamespacestd;
voidreverse(string s){
????boolflag = true;
????for(inti = 0; i < s.size();
i++){
????????cout<
- 1 - i];
????}???????
}
intmain(){
????string s;
????inti;
????while(cin>>s){
????????reverse(s);
????????cout<
????}
????return0;
}
[if !supportLists]11.?? [endif]手機鍵盤
//九宮格,相同格子的兩個字符如a、c分別需要按1、3次,如果一起按中間還需要等待,按鍵時間1s,等待時間2s, 求輸入給定串的時間
#include
usingnamespacestd;
intcount(string s){
????intsec, i;
????sec = 0;
????inttime[26] = {1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,4,1,2,3,1,2,3,4};
????inttable[26] =
{1,1,1,2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,6,7,7,7,8,8,8,8};
????charpre = '#';
????for(i = 0; i
< s.size(); i++){
????????if(table[pre
- 97] == table[s[i] - 97]){
????????????sec
+= 2;
????????}????
????????sec
+= time[s[i] - 97];
????????pre
= s[i];
????}
????returnsec;
}
intmain(){
????string s;
????while(cin>>s){
????????cout<
????}
????return0;
}
[if !supportLists]12.?? [endif]質因數的個數
//求1~10^9之間的一個正整數N的質因數個數
#include
usingnamespacestd;
intcount(intn){
????intc = 0;
????for(inti = 2; i * i <= n;
i++){
????????while(n
% i == 0){
????????????n
/= i;
????????????c++;
????????}
????????if(i
<= 1){
????????????break;
????????}
????}
????if(n >
1){
????????c++;
????}
????returnc;
}
intmain(){
????intn;
????while(cin>>n){
????????cout<
????}
????return0;
}
[if !supportLists]13.?? [endif]整數拆分
//不超過10^6的整數n,求其拆分成2的冪的和的方式的數目,輸出f(n)%10^9
#include
usingnamespacestd;
intcount(longn){
????longi;
????intval[1000000];
????for(i = 1; i
<= n; i++){
????????if(i
== 1){
????????????val[1]
= 1;
????????}elseif(i % 2){//odd
????????????val[i]
= val[i - 1];
????????}else{
????????????val[i]
= (val[i - 1] + val[i / 2]) % 1000000000;
????????}
????}
????returnval[n];
}
intmain(){
????longn;
????while(cin>>n){
????????cout<
????}
????return0;
}???
[if !supportLists]14.?? [endif]成績排序
//輸入學生信息,按照成績排序(從低到高)后輸出結果,如果成績相同則學號小的在前
#include
#include
#include
usingnamespacestd;
structStudent{
????intnum, grade;
};
boolcmp(Student a, Student
b){
????if(a.grade
< b.grade){
????????returntrue;
????}elseif(a.grade == b.grade
&& a.num < b.num){
????????returntrue;
????}else{
????????returnfalse;
????}
}
intmain(){
????intn;
????while(cin>>n){
vectorstu(n);//標識對象的長度
????????for(inti = 0; i < n; i++){
????????????cin>>stu[i].num>>stu[i].grade;
????????}
stable_sort(stu.begin(),stu.end(), cmp);//cmp標識排序規則
????????for(inti = 0; i < n; i++){
????????????cout<
"<
????????}
????}
????return0;
}
[if !supportLists]15.?? [endif]球半徑和體積
//已經球的中心電點和球上某一點的坐標,輸出保留到三位小數的半徑和體積。PI使用arccos(-1)
#include
#include
#include
usingnamespacestd;
intmain(){
????doubler, v;
????inta, b, c, d, e, f;
????while(cin>>a){
????????cin>>b>>c>>d>>e>>f;
????????r
= (double)sqrt((d - a) * (d - a) + (e - b) * (e - b) + (f - c) * (f - c));
????????v
= r * r * r * acos(-1) * 4 / 3;
????????cout<
"<
????}
????return0;
}
[if !supportLists]16.?? [endif]遍歷二叉樹
//根據讀入的先序遍歷的字符串建樹,然后輸出中序遍歷結果,如abc##de#g##f###,結果為c b e g d f a
#include
#include
using namespace std;
string str;
int i;
struct TreeNode{
??? char val;
??? struct TreeNode *lchild, *rchild;
??? TreeNode(char c): val(c), lchild(NULL), rchild(NULL){};
};
TreeNode *createTree(){
??? char c = str[i++];
??? if(c == '#'){
??????? return NULL;
??? }
??? TreeNode *root = new TreeNode(c);
??? root -> lchild = createTree();
??? root -> rchild = createTree();
??? return root;
}
void inOrderTraversal(TreeNode *root){
??? if(!root){
??????? return;
??? }
??? inOrderTraversal(root -> lchild);
??? cout< val<<" ";
??? inOrderTraversal(root -> rchild);
}
int main(){
??? while(cin>>str){
??????? TreeNode *root = createTree();
?????? ?inOrderTraversal(root);
??????? cout<
??? }
??? return 0;
}
[if !supportLists]17.?? [endif]瑪雅人的密碼
//對只含0、1、2的字符串,通過相鄰移動以出現2012來解開密碼,求最少移動次數
#include
usingnamespacestd;
conststring match =
"2012";
intmain(){
????intN;
????string str;
????while(cin>>N){
????????cin>>str;
????????queue
int> > que;
????????unordered_set
visit;
?????????for(N
= -1, que.push(make_pair(str, 0)), visit.insert(str); que.size(); que.pop()){
????????????pair
int> p = que.front();
????????????if(p.first.find(match)
!= string::npos){
????????????????N
= p.second;
????????????????break;
????????????}
????????????for(inti = 1; i <
p.first.length(); i++){
????????????????swap(p.first[i
- 1], p.first[i]);
????????????????if(visit.find(p.first)
== visit.end()){
????????????????????que.push(make_pair(p.first,
p.second + 1));
????????????????}
????????????????visit.insert(p.first);
????????????????swap(p.first[i
- 1], p.first[i]);
????????????}
????????}
????????cout<
????}
????return0;
}
[if !supportLists]18.?? [endif]求給定個數的n個整數中的最大最小值,每個數絕對值不大于10^6
#include
using namespace std;
int main(){
???int N;
???while(cin>>N){
??????? int a[N];
??????? for(int i = 0; i < N; i++){
??????????? cin>>a[i];
??????? }
??????? int max = a[0], min = a[0];
??????? for(int i = 0; i < N; i++){
??????????? min = min < a[i] ? min : a[i];
??????????? max = max < a[i] ? a[i] : max;
??????? }
??????? cout<
???}
???return 0;
}
[if !supportLists]19.?? [endif]最小郵票數
//求n張郵票湊成總面值為m所需要的最少郵票數,輸入n、m,以及接下來的n張郵票
#include
usingnamespacestd;
#define INF 0xFFFFFF
intminCount(intM, intN, inta[]){
????if(N == 0){
????????if(M
== 0){
????????????return0;
????????}else{
????????????returnINF;
????????}
????}elseif(M - a[N - 1] >=
0){
????????returnmin(minCount(M - a[N -
1], N - 1, a) + 1, minCount(M, N - 1, a));
????}else{
????????returnminCount(M, N - 1, a);
????}
}
intmain(){
????intM, N, count;
????while(cin>>M){
????????cin>>N;
????????inta[N];
????????for(inti = 0; i < N; i++){
????????????cin>>a[i];
????????}
????????count
= minCount(M, N, a) >= INF ? 0 : minCount(M, N, a);
????????cout<
????}
????return0;
}
[if !supportLists]20.??[endif]abc
//求使兩個整數abc、bcc滿足abc+bcc=532的所有a、b、c的值
//答案為3 2 1
#include
using namespace std;
int main(){
???int a, b, c;
???for(a = 0; a < 6; a++){
??????? for(b = 0; b < 6; b++){
??????????? for(c = 0; c < 7; c++){
??????????????? if(a * 100 + b * 110 + c * 12== 532){
??????????????????? cout<
??????????????? }
??????????? }
??????? }
???}
???return 0;
}
[if !supportLists]21.??[endif]root(N, k)
//題目:N=2000000000)
#include
using namespace std;
int main(){
???for(long x, y, k, r; cin>>x>>y>>k;){
??????? for(r = 1, k -= 1; y; r = (y & 1 ?r * x % k : r) , x = x * x % k , y >>= 1);
??????? cout<<(r ? r : k)<
???}
???return 0;
}
[if !supportLists]22.?? [endif]N的階乘
//求1~20之間的整數的階乘
#include
using namespace std;
double factorial(double n){
???if(n > 0){
??????? return n * factorial(n - 1);
???}else{
??????? return 1;
???}
}
int main(){
???int n;
???while(cin>>n){
???????cout<
???}
???return 0;
}
[if !supportLists]23.?? [endif]特殊乘法
/題目:/對2個小于1000000000的輸入,求結果。 特殊乘法舉例:123* 45 = 1*4 +1*5 +2*4 +2*5 +3*4+3*5
#include
using namespace std;
int special(string m, string n){
???int i, j, sum;
???sum = 0;
???for(i = 0; i < m.length(); i++){
??????? for(j = 0; j < n.length(); j++){
??????????? sum += (m[i] - '0') * (n[j] - '0');
??????? }
???}
???return sum;
}
int main(){
???string m, n;
???while(cin>>m){
??????? cin>>n;
??????? cout<
???}
???return 0;
}
[if !supportLists]24.?? [endif]今年的第幾天
//題目:輸入年、月、日,計算該天是本年的第幾天
//這么循環非常簡練了
#include
using namespace std;
const int month[13] = {0, 31, 28,31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int main(){
???for(int y, m, d; cin>>y>>m>>d;cout<
??????? for(int i = 1; i < m; d +=month[i++]);
??????? if(y % 400 == 0 || (y % 100 &&y % 4 == 0)){
??????????? d += m > 2 ? 1 : 0;
??????? }
???}
???return 0;
}
[if !supportLists]25.?? [endif]完數vs盈數
//題目:一個數如果恰好等于它的各因子(該數本身除外)子和,如:6=3+2+1。則稱其為“完數”;若因子之和大于該數,則稱其為“盈數”。 求出2到60之間所有“完數”和“盈數”。
#include
using namespace std;
int main(){
???int n, i, s, c, g[60];
???for(cout<<"E:", c = 0, n = 2; n < 61; n++){
??????? for(s = 0, i = 1; i < n; s += (n % i? 0 : i), i++);
??????? if(s == n){
??????????? cout<<" "<
??????? }else if(s > n){
??????????? g[c++] = n;
??????? }
???}
???for(cout<<"\nG:", i = 0; i < c; cout<<""<
???cout<
???return 0;
}
[if !supportLists]26.?? [endif]遞推數列
//題目:給定a0,a1,以及an=p*a(n-1) + q*a(n-2)中的p,q。這里n >= 2。 求第k個數對10000的模。輸入:a0、a1、p、q、k,輸出:第k個數a(k)對10000的模
//考點:遞推,非遞歸方法?
//時間復雜度:O(n)
#include
using namespacestd;?
int main(){
??? int a0, a1, p, q, k, result;
???while(cin>>a0>>a1>>p>>q>>k){
??????? for(int i = 2; i <= k; i++){
??????????? result = (q * a0 + p * a1) %10000;//中間部分就需要取余
??????????? a0 = a1;//相當于將oneback用twoback賦值
??????????? a1 = result;
??????? }
??????? cout<<(result %10000)<
??? }
??? return 0;
}
?
?
?
三、部分leetcode(少筆記)
1.二叉樹的最小深度
//題目:Givena binary tree, find its minimum depth.The minimum depth is the number of nodesalong the shortest path from the root node down to the nearest leaf node.
class Solution{
public:
??? int run(TreeNode *head){
??????? if(!head){
??????????? return 0;
??????? }
??????? int l = run(head -> left);//依次遍歷
??????? int r = run(head -> right);
??????? if(l == 0 || r == 0){//為左空或者右空
??????????? return 1 + l + r;
??????? }
??????? return 1 + min(l, r);//選小
??? }
};
[if !supportLists]2. [endif]計算逆波蘭表達式
//題目:Evaluatethe value of an arithmetic expression inReverse
Polish Notation. Valid operators are+,-,*,/. Each operand may be aninteger or another expression. Some examples:
["2","1", "+", "3", "*"] -> ((2 + 1) * 3)-> 9
["4","13", "5", "/", "+"] -> (4 + (13 /5)) -> 6
class Solution{
public:
??? int evalRPN(vector &s){
??????? stack store;
??????? for(auto x : s){
??????????? if(x == "+" || x=="-" || x == "*" || x =="/"){//雙引號
??????????????? int a = store.top();store.pop();
??????????????? int b = store.top();store.pop();
??????????????? int c = 0;
??????????????? if(x == "+"){
??????????????????? c = b + a;
??????????????? }else if(x == "-"){
??????????????????? c = b - a;
??????????????? }else if(x == "*"){
??????????????????? c = b * a;
??????????????? }else{
??????????????????? c = b / a;
??????????????? }
??????????????? store.push(c);
??????????? }else{
??????????????? store.push(atoi(x.c_str()));
??????????? }
??????? }
??????? return store.top();
??? }
};
[if !supportLists]3. [endif]最大點數
//題目:Givenn points on a 2D plane, find the maximum number of points that lie on the samestraight line.
class Solution{
public:
??? int maxPoints(vector&points){
??????? int size = points.size();
??????? int ans = size < 2 ? size : 2;
??????? for(int i = 0; i < size; i++){
??????????? int count_i = 0;//與i重合的點數
??????????? for(int j = i + 1; j < size;j++){
??????????????? int count_i_j = 1;//與i,j共線的點數
??????????????? if(points[i].x == points[j].x&& points[i].y == points[j].y){
??????????????????? count_i++;
??????????????? }else{
??????????????????? for(int t = j; t < size;t++){
??????????????????????? if((points[i].x -points[j].x) * (points[t].y - points[j].y)
??????????????????????? == (points[t].x -points[j].x) * (points[i].y - points[j].y)){
??????????????????????????? count_i_j++;
?????????????????????? ?}
??????????????????? }
??????????????? }
??????????????? ans = max(ans, count_i +count_i_j);
??????????? }
??????? }
???????? return ans;???????
??? }
};
[if !supportLists]4. [endif]列表排序
//題目:Sorta linked list in O(n log n) time using constant space complexity.
/**
?* Definition for singly-linked list.
?* struct ListNode {
?*????int val;
?*????ListNode *next;
?*????ListNode(int x) : val(x), next(NULL) {}
?* };
?*/
class Solution{
public:
??? static int cmp(ListNode *a, ListNode *b){
??????? return a -> val < b -> val;
??? }
??? ListNode *sortList(ListNode *head){
??????? if(!head){
??????????? return NULL;
??????? }
??????? vector arr;
??????? ListNode *p;
??????? p = head;
??????? while(p){
??????????? arr.push_back(p);
??????????? p = p -> next;
????? ??}
??????? sort(arr.begin(), arr.end(), cmp);
??????? p = head = arr[0];
???????? for(int i = 0; i < arr.size(); i++){
??????????? p -> next = arr[i];
??????????? p = p -> next;
??????? }
??????? p -> next = NULL;
??????? arr[arr.size() - 1] -> next = NULL;
??????? return head;
??? }
};
[if !supportLists]5. [endif]對列表插入排序
//題目:Sorta linked list using insertion sort.
/**
?* Definition for singly-linked list.
?* struct ListNode {
?*????int val;
?*????ListNode *next;
?*????ListNode(int x) : val(x), next(NULL) {}
?* };
?*/
class Solution{
public:
???? ListNode *insertionSortList(ListNode *head){
???????? if(!head || !head -> next){
??????????? return head;
??????? }???????
??????? ListNode L(0), *p;//L:object
??????? L.next = insertionSortList(head ->next);//recursion
??????? p = &L;
??????? while(p && p -> next&& p -> next -> val < head -> val){
??????????? p = p -> next;
??????? }
??????? head -> next = p -> next;
??????? p -> next = head;
??????? return L.next;
??? }
};???????