數據結構與算法——2018期末機考練習


寫在前面

1.2018期末機考題目網址:

(1)普通班:http://dsa.openjudge.cn/final20181223

(2)實驗班:http://dsa.openjudge.cn/final2018ht

2.2018期末機考模擬測試:

http://dsa.openjudge.cn/2018ftest/

3.參考資料下載地址

(1)http://media.openjudge.cn/upload/DSMooc/DSCode_ZhangWangZhao2008_06.rar

(2)http://media.openjudge.cn/upload/DSMooc/DScodeCversion.rar (C語言代碼包)

(3)http://media.openjudge.cn/upload/DSMooc/201810cplusplus.zip (C++手冊)

(4)http://media.openjudge.cn/upload/DSMooc/DSAlgoWeissMark.pdf (英文教材)

 

1.詞典

其他網址:http://bailian.openjudge.cn/practice/2804/

題目  

總時間限制: 
3000ms
內存限制: 
65536kB
描述

你旅游到了一個國外的城市。那里的人們說的外國語言你不能理解。不過幸運的是,你有一本詞典可以幫助你。

輸入
首先輸入一個詞典,詞典中包含不超過100000個詞條,每個詞條占據一行。每一個詞條包括一個英文單詞和一個外語單詞,兩個單詞之間用一個空格隔開。而且在詞典中不會有某個外語單詞出現超過兩次。詞典之后是一個空行,然后給出一個由外語單詞組成的文檔,文檔不超過100000行,而且每行只包括一個外語單詞。輸入中出現單詞只包括小寫字母,而且長度不會超過10。
輸出
在輸出中,你需要把輸入文檔翻譯成英文,每行輸出一個英文單詞。如果某個外語單詞不在詞典中,就把這個單詞翻譯成“eh”。
樣例輸入
dog ogday
cat atcay
pig igpay
froot ootfray
loops oopslay

atcay
ittenkay
oopslay
樣例輸出
cat
eh
loops
提示
  輸入比較大,推薦使用C語言的I / O函數。
來源
  翻譯自Waterloo local 2001.09.22的試題

我的代碼

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <algorithm>
 4 # include <string.h>
 5 using namespace std;  6 
 7 //type: DIC
 8 typedef struct{  9     char w1[12], w2[12]; 10 } DIC; 11 
12 //d1.w1 < d2.w1
13 bool cmp(DIC d1, DIC d2){ 14     return (strcmp(d1.w2, d2.w2) < 0); 15 } 16 
17 
18 DIC d[100010];  //dictionary: increasing order
19 int n = 0;      //n pairs of words in dic
20 char s[25];     //input strings s[] 21 
22 //initialize dictionary: separate 2 words
23 void IniDic(int num){ 24     int pos; 25     for(pos = 0; s[pos] != ' '; ++pos); 26  strncpy(d[num].w1, s, pos); 27     strncpy(d[num].w2, s+pos+1, 11); 28 } 29 
30 //binary search: lookfor word s[]
31 void SearchWord(){ 32     int r = 0, l = n - 1, m, t;   //first, last, middle
33     while(r < l){ 34         m = (r + l) / 2; 35         if((t = strcmp(s, d[m].w2)) == 0){ 36             printf("%s\n", d[m].w1); 37             return;     //find s = d[m].w1
38  } 39         else if(t > 0)  //s > d[m].w1
40             r = m + 1; 41         else            //s < d[m].w1
42             l = m - 1; 43  } 44     if(strcmp(s, d[r].w2) == 0) 45         printf("%s\n", d[r].w1); 46     else
47         printf("eh\n"); 48     return; 49 } 50 
51 int main(){ 52     while((s[0] = cin.get()) != '\n'){ 53         cin.getline(s+1, 24); 54         IniDic(n++); 55  } 56     //cout << n << endl;
57     sort(d, d+n, cmp);  //sort dictionary 58     //for(int i = 0; i < n; ++i) 59         //printf("dic[%d]: %s %s\n", i, d[i].w1, d[i].w2);
60     while(cin >> s){ 61  SearchWord(); 62  } 63     return 0; 64 }
View Code

tips

1.空行的識別,get(),cin.getline()等

2.單詞排序:定義比較函數<template T> bool cmp(T t1, T t2);

3.單詞查找:二分查找

 

 

2.Field Reduction

來源:USACO 2016 US Open contest

題目 

總時間限制: 
10000ms
 
單個測試點時間限制: 
1000ms
 
內存限制: 
65536kB
描述

Farmer John's N cows (5≤N≤50,000) are all located at distinct positions in his two-dimensional field. FJ wants to enclose all of the cows with a rectangular fence whose sides are parallel to the x and y axes, and he wants this fence to be as small as possible so that it contains every cow (cows on the boundary are allowed). FJ is unfortunately on a tight budget due to low milk production last quarter. He would therefore like to build an even smaller fenced enclosure if possible, and he is willing to sell up to three cows from his herd to make this possible. Please help FJ compute the smallest possible area he can enclose with his fence after removing up to three cows from his herd (and thereafter building the tightest enclosing fence for the remaining cows). For this problem, please treat cows as points and the fence as a collection of four line segments (i.e., don't think of the cows as "unit squares"). Note that the answer can be zero, for example if all remaining cows end up standing in a common vertical or horizontal line.  

農夫約翰的N(5<=N<=50000)頭牛被定在了平面內的不同的位置。他想用柵欄(平行於x和y軸)圍住所有的牛。他想這個柵欄盡可能小(牛在邊界上也被視作圍住)。

他因為牛奶產量低而感到經費緊張,所以他想賣掉三頭牛再圍起剩下的牛。請算出柵欄圍出的最小面積。(面積有可能為0,例如,最后剩下的牛排成一排或一列。)

輸入
The first line of input contains N. The next N lines each contain two integers specifying the location of a cow. Cow locations are positive integers in the range 1…40,000.

第一行輸入正整數n

剩下2-n+1行,輸入每頭牛的坐標位置(x,y) ( 1<= x,y<=40000的整數)

輸出
Write a single integer specifying the minimum area FJ can enclose with his fence after removing up to three carefully-chosen cows from his herd.
最小面積
樣例輸入
6
1 1
7 8
10 9
8 12
4 100
50 7
樣例輸出
12

思路

按x、y的大小分別排序,每次去掉xmin/xmax/ymin/ymax的一頭牛,dfs或者直接枚舉

我的代碼

(只在本地測試了一些數據)

版本一:

 1 # include <iostream>
 2 # include <algorithm>
 3 using namespace std;  4 #define MAXSPACE 2000000000
 5 
 6 //cow's position
 7 typedef struct{  8     int x, y;  9 } COW; 10 
11 //compare cow's x
12 bool cmpx(COW c1, COW c2){ 13     return c1.x < c2.x; 14 } 15 
16 //compare cow's y
17 bool cmpy(COW c1, COW c2){ 18     return c1.y < c2.y; 19 } 20 
21 int n; 22 COW * c; 23 
24 //find min from 4 values
25 int MyMin(int a, int b, int c, int d){ 26     if(a < b){ 27         if(a < c){ 28             if(a < d) return a; 29             else return d; 30  } 31         else{ 32             if(c < d) return c; 33             else return d; 34  } 35  } 36     else{ 37         if(b < c){ 38             if(b < d) return b; 39             else return d; 40  } 41         else{ 42             if(c < d) return c; 43             else return d; 44  } 45  } 46 } 47 
48 //calculate min space needed after selling r cows from c[s~e-1]
49 int MinSpace(int s, int e, int r){ 50     if(r == 0){ //no cows to sell
51         int x1, x2, y1, y2; 52         sort(c+s, c+e, cmpx); 53         x1 = c[s].x; 54         x2 = c[e-1].x; 55         sort(c+s, c+e, cmpy); 56         y1 = c[s].y; 57         y2 = c[e-1].y; 58         return (x2-x1)*(y2-y1); 59  } 60     int mx1 = MAXSPACE, mx2 = MAXSPACE, my1 = MAXSPACE, my2 = MAXSPACE; 61     sort(c+s, c+e, cmpx); 62     //sell the cow with min-x 63     //if c[s].x == c[s+3].x, then selling cow s won't make space smaller (from x's perspective)
64     if(s+3 < e && c[s].x != c[s+3].x) 65         mx1 = MinSpace(s+1, e, r-1); 66     //sell the cow with max-x
67     if(s+3 < e && c[e-4].x != c[e-1].x) 68         mx2 = MinSpace(s, e-1, r-1); 69     sort(c+s, c+e, cmpy); 70     //sell the cow with min-y
71     if(s+3 < e && c[s].y != c[s+3].y) 72         my1 = MinSpace(s+1, e, r-1); 73     //sell the cow with max-y
74     if(s+3 < e && c[e-4].y != c[e-1].y) 75         my2 = MinSpace(s, e-1, r-1); 76     return MyMin(mx1, mx2, my1, my2); 77 } 78 
79 int main(){ 80     cin >> n; 81     c = new COW[n+1]; 82     for(int i = 0; i < n; ++i) 83         cin >> c[i].x >> c[i].y; 84     cout << MinSpace(0, n, 3) << endl; 85     delete [] c; 86     return 0; 87 }
View Code

有很多重復的sort,非常耗時

版本二:

 1 # include <iostream>
 2 # include <algorithm>
 3 # include <cstdio>
 4 using namespace std;  5 #define MAXSPACE 2000000000
 6 
 7 //cow's position
 8 typedef struct{  9     int x, y; 10 } COW; 11 
12 //compare cow's x
13 bool cmpx(COW c1, COW c2){ 14     return c1.x < c2.x; 15 } 16 
17 //compare cow's y
18 bool cmpy(COW c1, COW c2){ 19     return c1.y < c2.y; 20 } 21 
22 int n, ans = MAXSPACE; 23 COW * c; 24 
25 //min value of a & b
26 int MyMin(int a, int b){ 27     if(a < b) return a; 28     else return b; 29 } 30 
31 //calculate space needed 32 //after selling x1 cows with min-x, x2 cows with max-x, 33 //and selling y1 cows with min-y, y2 cows with max-y
34 void Space(int x1, int x2, int y1, int y2){ 35     sort(c, c+n, cmpx); 36     sort(c+x1, c+n-x2, cmpy); 37     int miny = c[x1+y1].y, maxy = c[n-x2-y2-1].y; 38     sort(c+x1+y1, c+n-x2-y2, cmpx); 39     int minx = c[x1+y1].x, maxx = c[n-x2-y2-1].x; 40     int s = (maxx - minx) * (maxy - miny); 41     /* testing code */
42     /*
43  printf("%d %d %d %d %d\n", x1,x2,y1,y2, s); 44  printf(" x: %d-%d, y: %d-%d\n ", minx,maxx, miny, maxy); 45  for(int i=0; i<n; ++i) 46  printf("(%d,%d) ", c[i].x, c[i].y); 47  printf("\n"); 48     */
49     ans = MyMin(s, ans); 50 } 51 
52 int main(){ 53     cin >> n; 54     c = new COW[n+1]; 55     for(int i = 0; i < n; ++i) 56         cin >> c[i].x >> c[i].y; 57     for(int i = 0; i <= 3; ++i) 58         for(int j = 0; i+j <= 3; ++j) 59             for(int k = 0; i+j+k <= 3; ++k) 60                 Space(i, j, k, 3-i-j-k); 61     cout << ans << endl; 62     delete [] c; 63     return 0; 64 }
View Code

枚舉要去掉的牛的位置和個數

 

 

3.Ultra-QuickSort

其他網址:http://bailian.openjudge.cn/practice/2299/

題目

總時間限制: 
7000ms
 
內存限制: 
65536kB
描述
In this problem, you have to analyze a particular sorting algorithm. The algorithm processes a sequence of n distinct integers by swapping two adjacent sequence elements until the sequence is sorted in ascending order. For the input sequence 
9 1 0 5 4 , 

Ultra-QuickSort produces the output 
0 1 4 5 9 . 

Your task is to determine how many swap operations Ultra-QuickSort needs to perform in order to sort a given input sequence. 
輸入
The input contains several test cases. Every test case begins with a line that contains a single integer n < 500,000 -- the length of the input sequence. Each of the the following n lines contains a single integer 0 ≤ a[i] ≤ 999,999,999, the i-th input sequence element. Input is terminated by a sequence of length n = 0. This sequence must not be processed.
輸出
For every input sequence, your program prints a single line containing an integer number op, the minimum number of swap operations necessary to sort the given input sequence.
樣例輸入
5
9
1
0
5
4
3
1
2
3
0
樣例輸出
6
0
來源
Waterloo local 2005.02.05

我的代碼

 1 # include <cstdio>
 2 using namespace std;  3 
 4 int main(){  5     int n, a[500000], cnt, tmp;  6     scanf("%d", &n);  7     while(n){  8         cnt = 0;  9         for(int i = 0; i < n; ++i) 10             scanf("%d", a + i); 11         for(int i = n - 1; i; --i) 12             for(int j = 0; j < i; ++j){ 13                 if(a[j] > a[j+1]){ 14                     tmp = a[j]; 15                     a[j] = a[j+1]; 16                     a[j+1] = tmp; 17                     ++cnt; 18  } 19  } 20         printf("%d\n", cnt); 21         scanf("%d", &n); 22  } 23     return 0; 24 }
一次傻傻的冒泡
 1 # include <cstdio>
 2 using namespace std;  3 
 4 int main(){  5     int n, a[500000], cnt, tmp;  6     bool f;    //flag
 7     scanf("%d", &n);  8     while(n){  9         cnt = 0; 10         for(int i = 0; i < n; ++i) 11             scanf("%d", a + i); 12         for(int i = n - 1; i; --i){ 13             f = 1;            //flag
14             for(int j = 0; j < i; ++j){ 15                 if(a[j] > a[j+1]){ 16                     tmp = a[j]; 17                     a[j] = a[j+1]; 18                     a[j+1] = tmp; 19                     ++cnt; 20                     f = 0;    //flag
21  } 22  } 23             if(f) break; 24  } 25         printf("%d\n", cnt); 26         scanf("%d", &n); 27  } 28     return 0; 29 }
一次不死心的優化的冒泡

冒泡(復雜度O(n^2))妥妥TLE

換了歸並(復雜度O(nlgn)),終於AC

 1 # include <cstdio>
 2 using namespace std;  3 
 4 //length n, array a[], temp array t[]
 5 int n, a[500000], t[500000];  6 
 7 //Merge(start, middle, end)
 8 long long Merge(int s, int m, int e){  9     int i = s, j = m+1, k = s; 10     long long cnt = 0; 11     while(i <= m && j <= e){ 12         if(a[i] < a[j]) 13             t[k++] = a[i++]; 14         else{ 15             t[k++] = a[j++]; 16             cnt += j - k;   //a[j] go to a[k] needs j-k exchanges
17  } 18  } 19     while(i <= m) t[k++] = a[i++]; 20     while(j <= e) t[k++] = a[j++]; 21     for(int l = s; l <= e; ++l) 22         a[l] = t[l]; 23     return cnt; 24 } 25 
26 //Divide & sort & merge
27 long long MergeSort(int s, int e){ 28     if(s >= e) return 0;    //exit of recursion
29     int m = (s + e) / 2; 30     long long ret = 0; 31     ret += MergeSort(s, m);     //sort a[s~m]
32     ret += MergeSort(m + 1, e); //sort a[m+1~e]
33     ret += Merge(s, m, e);      //merge a[s~m] & a[m+1~e]
34     return ret; 35 } 36 
37 int main(){ 38     scanf("%d", &n); 39     while(n){ 40         for(int i = 0; i < n; ++i) 41             scanf("%d", a + i); 42         printf("%lld\n", MergeSort(0, n-1)); 43         scanf("%d", &n); 44  } 45     return 0; 46 }
AC

tips:

1.注意數據類型用long long (親測int會WA)

2.采用歸並排序,記錄歸並過程中記錄交換次數(AC代碼第16行:cnt += j-k 或 cnt += m-i+1)

 

 

4.表達式·表達式樹·表達式求值

其他網址:http://dsa.openjudge.cn/tree/0609/

題目

總時間限制: 
1000ms
 
內存限制: 
65535kB
描述

眾所周知,任何一個表達式,都可以用一棵表達式樹來表示。例如,表達式a+b*c,可以表示為如下的表達式樹:

   +
  / \
a   *
    / \
    b c

現在,給你一個中綴表達式,這個中綴表達式用變量來表示(不含數字),請你將這個中綴表達式用表達式二叉樹的形式輸出出來。

輸入
輸入分為三個部分。
第一部分為一行,即中綴表達式(長度不大於50)。中綴表達式可能含有小寫字母代表變量(a-z),也可能含有運算符(+、-、*、/、小括號),不含有數字,也不含有空格。
第二部分為一個整數n(n < 10),表示中綴表達式的變量數。
第三部分有n行,每行格式為C x,C為變量的字符,x為該變量的值。
輸出
輸出分為三個部分,第一個部分為該表達式的逆波蘭式,即該表達式樹的后根遍歷結果。占一行。
第二部分為表達式樹的顯示,如樣例輸出所示。如果該二叉樹是一棵滿二叉樹,則最底部的葉子結點,分別占據橫坐標的第1、3、5、7……個位置(最左邊的坐標是1),然后它們的父結點的橫坐標,在兩個子結點的中間。如果不是滿二叉樹,則沒有結點的地方,用空格填充(但請略去所有的行末空格)。每一行父結點與子結點中隔開一行,用斜杠(/)與反斜杠(\)來表示樹的關系。/出現的橫坐標位置為父結點的橫坐標偏左一格,\出現的橫坐標位置為父結點的橫坐標偏右一格。也就是說,如果樹高為m,則輸出就有2m-1行。
第三部分為一個整數,表示將值代入變量之后,該中綴表達式的值。需要注意的一點是,除法代表整除運算,即舍棄小數點后的部分。同時,測試數據保證不會出現除以0的現象。
樣例輸入
a+b*c
3
a 2
b 7
c 5
樣例輸出
abc*+
   +
  / \
 a   *
    / \
    b c
37

我的代碼 

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <stack>
 4 using namespace std;  5 
 6 char a[20], b[20], c;   //input a[], answer b[]
 7 char ** pic;    //picture of tree
 8 int v[30], n, t;//v[] store values
 9 int len;        //len = lenght of b[]
 10 int pos;        //current index when biulding tree
 11 int dep = 0;    //depth of tree
 12 stack<int> st1; //help calculate  13 
 14 //define Node of binary tree
 15 typedef struct NODE{  16     char c;     //symbol of node
 17     int d;      //depth of node
 18     NODE *l, *r;//pointer to children
 19 } Node;  20 
 21 Node * root, * cur;  22 
 23 //biuld the subtree with root b[l]
 24 Node * BiuldSubtree(int d){  25     Node * tmp = new Node;  26     tmp->c = b[pos--];        //set node's symbol
 27     tmp->d = d;             //set node's depth
 28     if(d > dep) dep = d;    //renew depth of tree
 29     if(tmp->c >= 'a' && tmp->c <= 'z')  30         tmp->l = tmp->r = NULL; //leaf nodes (variables)
 31     else{                       //branch nodes (operators)
 32         tmp->r = BiuldSubtree(d+1);  33         tmp->l = BiuldSubtree(d+1);  34  }  35     return tmp;  36 }  37 //Biuld binary tree
 38 void BiuldTree(){  39     pos = len-1;  //current position of b[]
 40     root = BiuldSubtree(0);  41     //printf("depth = %d\n", dep);
 42 }  43 //delete Tree
 44 void DelTree(Node * ptr){  45     if(ptr == NULL) return;  46     DelTree(ptr->l);  47     DelTree(ptr->r);  48     delete ptr;  49 }  50 //Draw the subtree ptr pointing to from (si, sj) in pic[][]
 51 void DrawSubtree(Node * ptr, int si, int sj){  52     if(ptr == NULL) return;     //draw nothing
 53     int i = si, j = sj + (1<<(dep-ptr->d)) - 1;  54     pic[i][j] = ptr->c;  55     if(ptr->l == NULL) return;  //leaf node
 56     pic[i+1][j-1] = '/';  57     pic[i+1][j+1] = '\\';  58     DrawSubtree(ptr->l, i+2, sj);  59     DrawSubtree(ptr->r, i+2, j+1);  60 }  61 //print binary tree
 62 void PrintTree(){  63     int h = dep*2+1, w = 1<<(dep+1);  64     int i, j;  65     //initialize pic[][]
 66     pic = new char * [h];  67     for(i = 0 ; i < h; ++i){  68         pic[i] = new char[w];  69         for(j = 0; j < w; ++j)  70             pic[i][j] = ' ';  71  }  72     //draw nodes in pic[][]
 73     DrawSubtree(root, 0, 0);  74     //don't print ending spaces
 75     for(i = 0 ; i < h; ++i){  76         for(j = w-1; pic[i][j] == ' '; --j);  77         pic[i][j+1] = '\0';  78         printf("%s\n", pic[i]);  79  }  80 }  81 
 82 
 83 //print reverse Polish notation b[]
 84 void PrintB(){  85     stack<char> st;  86     len = 0;  87     for(int i = 0; a[i]; ++i){  88         switch(a[i]){  89             case '(': st.push(a[i]); break;  90             case ')':  91                 while((c = st.top()) != '('){  92                     b[len++] = c;  93  st.pop();  94  }  95                 st.pop(); break;  96             case '+':  97             case '-':  98                 while(!st.empty() && (c = st.top()) != '('){  99                     b[len++] = c; 100  st.pop(); 101  } 102                 st.push(a[i]); break; 103             case '*': 104             case '/': 105                 while(!st.empty() && ((c = st.top()) == '*' || c == '/')){ 106                     b[len++] = c; 107  st.pop(); 108  } 109                 st.push(a[i]); break; 110             default:    //variables
111                 b[len++] = a[i]; 112  } 113  } 114     while(!st.empty()){     //don't forget remaining symbols
115         b[len++] = st.top(); 116  st.pop(); 117  } 118     printf("%s\n", b); 119 } 120 
121 //calculate t3 = t1 op t2
122 void Cal2Nums(char op){ 123     int t1, t2, t3; 124     //t1 under t2, pop t2 first
125     t2 = st1.top(); st1.pop(); 126     t1 = st1.top(); st1.pop(); 127     switch(op){ 128         case '+': t3 = t1 + t2; break; 129         case '-': t3 = t1 - t2; break; 130         case '*': t3 = t1 * t2; break; 131         case '/': t3 = t1 / t2; break; 132         default: 133             printf("Error in Cal2Nums\n!!"); 134             exit(0); 135  } 136  st1.push(t3); 137 } 138 //calculate answer of b[]
139 void CalAns(){ 140     for(int i = 0; b[i]; ++i){ 141         if(b[i] >= 'a' && b[i] <= 'z') 142             st1.push(v[b[i]-'a']); 143         else
144  Cal2Nums(b[i]); 145  } 146     printf("%d\n", st1.top()); 147  st1.pop(); 148 } 149 
150 
151 int main(){ 152     cin >> a >> n; 153     for(int i = 0; i < n; ++i){ 154         cin >> c >> t; 155         v[c-'a'] = t; 156  } 157  PrintB(); 158  BiuldTree(); 159  PrintTree(); 160  DelTree(root); 161  CalAns(); 162     return 0; 163 }
View Code

思路不難,就是麻煩,估計考試的時候寫不完quq

 

5.Angry Cows

題目

總時間限制: 
10000ms
 
單個測試點時間限制: 
1000ms
 
內存限制: 
65536kB
描述

奶牛Bessie設計了一個游戲:“憤怒的奶牛”。游戲的原型是:有一些可爆燃的草堆分布在一條數軸的不同坐標,玩家用彈弓把奶牛發射到數軸上。牛奶砸到數軸上的沖擊波會引發附近的草堆燃爆,並有可能引起附近的草堆連環燃爆。游戲的目標是玩家用一些奶牛燃爆所有的草堆。 有N個草堆在數軸的不同位置,坐標為x1,x2,….,xn。如果玩家把奶牛發射到坐標是x,能量是R,就會引爆半徑R以內的的草堆,即坐標范圍[x-R, x+R]的草堆都會燃爆。 現在有K頭奶牛,每頭奶牛的能量都是R,請計算

輸入
第一行:2個整數N( 1 ≤ N ≤ 50,000)和K( 1 ≤ K ≤ 10)。
下面有N行,每行一個整數:x1, x2 ,…,xn,范圍在[0…1,000,000,000]
輸出
輸出最小可能的整數R。
樣例輸入
7 2
20
25
18
8
10
3
1
樣例輸出
5
提示
說明:只有一開始的牛會產生的爆炸,范圍為R,草堆並不會爆炸,只會受到牛能量的影響被引燃。

我的代碼 

 

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <algorithm>
 4 using namespace std;
 5 
 6 int N, K;
 7 int * pos, rmax, rmin, r, ans;
 8 
 9 int findnext(int i, int p){
10     for(i += 1; i < N && pos[i] <= p; ++i);
11     return i;
12 }
13 
14 int main(){
15     scanf("%d %d", &N, &K);
16     pos = new int[N+1];
17     for(int i=0; i<N; ++i)
18         scanf("%d", pos+i);
19     sort(pos, pos+N);
20     
21     rmin = 0;
22     rmax = (pos[N-1]-pos[0]) / (2*K) + 1;
23     while(rmin < rmax){
24         r = (rmin+rmax) / 2;
25         int k=0, i=0;
26         while(i < N){
27             ++k;
28             i = findnext(i, pos[i] + 2 * r);
29         }
30         if(k > K) rmin = r + 1;
31         else rmax = r;
32     }
33     printf("%d\n", rmin);
34     delete [] pos;
35     return 0;
36 }
View Code

 

6.廣告計划

題目

總時間限制: 
20000ms
 
單個測試點時間限制: 
2000ms
 
內存限制: 
65536kB
描述

作為一個新廣告項目的一部分,氪星的一家大公司打算把自己的logo在城市的某個地方展示。這家公司打算把這一整年的廣告預算都花在這個大logo上,所以它將會非常非常的大。公司的一位高管打算使用整個建築作為logo的一部分。

Logo由n個不同高度的柱子構成,從左到右編號為1到n。logo可以用編號1,2,……,n的一個排列(s1,s2...,sn)描述。其中s1代表最矮的柱子,s2是第二矮的,以此類推sn是最高的柱子。柱子的實際高度並不重要。

氪星的主干道旁有m棟建築,很奇怪的是這些建築的高度是不同的。現在的問題是找到所有可以與logo匹配的建築的位置。

幫助公司找到建築序列中所有可以與logo匹配的連續的部分,要求如下:s1最矮,s2是第二矮的,以此類推。例如一組建築的高度為5,10,4和用排列(3,1,2)描述的logo是匹配的,因為3號建築高為4,是最矮的,1號建築是第二矮的而建築2是最高的。

輸入
第一行包含兩個整數n和m(2<=n<=m<=1000000).
第二行包含n個整數,描述了序號1到n的一個排列si,其中1≤si≤n,si≠sj for i≠j .
第三行包含m個整數,表示了每棟樓的高度(小於等於10的9次方),其中兩兩不同,用空格分開。
輸出
第一行,整數k,匹配的個數。
第二行包含k個整數,表示匹配的位置,升序表示,如果k為0,則第二行為空。
樣例輸入
5 10
2 1 5 3 4
5 6 3 8 12 7 1 10 11 9
樣例輸出
2
2 6
提示
說明:6,3,8,12,7和7,1,10,11,9都可以匹配(2,1,5,3,4),在第一個序列中,2號建築高為3是最矮的,1號是第二矮的,接下來是5號建築高度為7排第三,最高的是4號高度為12.(如圖)

我的代碼

 1 # include <cstdio>
 2 # include <iostream>
 3 # include <algorithm>
 4 using namespace std;  5 
 6 int main(){  7     int n, m, * s, * h;  8     int tmp, cnt = 0, * ans;  9     bool f; 10     scanf("%d %d", &n, &m); 11     s = new int[n+2]; 12     h = new int[m+2]; 13     ans = new int[m-n+2]; 14     for(int i = 0; i < n; ++i) 15         scanf("%d", s + i); 16     for(int i = 0; i < m; ++i) 17         scanf("%d", h + i); 18     for(int i = -1; i < m - n; ++i){ 19         f = 1;      //start from i is OK
20         tmp = h[i+s[0]];   //current height
21         for(int j = 1; j < n; ++j){ 22             if(tmp >= h[i+s[j]]) 23             {   f = 0; break; } 24             else
25                 tmp = h[i+s[j]]; 26  } 27         if(f) 28             ans[cnt++] = i+2; 29  } 30     printf("%d\n", cnt); 31     for(int i = 0; i < cnt; ++i) 32         printf("%d ", ans[i]); 33     delete [] s; 34     delete [] h; 35     delete [] ans; 36     return 0; 37 }
View Code

太暴力了,果然TLE... 畢竟去年考試只有14人通過orz

我還沒AC...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM