noip2015 day1


  不解释,很简单,直接按照题目的方法构造就行了

Code

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<map>
 6 #include<set>
 7 #include<queue>
 8 #include<vector>
 9 #include<algorithm>
10 using namespace std;
11 typedef bool boolean;
12 template<typename T>
13 inline void readInteger(T& u){
14     char x;
15     while(!isdigit((x = getchar())));
16     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
17     ungetc(x, stdin);
18 }
19 
20 template<typename T>class Matrix{
21     public:
22         T* p;
23         int width;
24         int height;
25         Matrix():width(0), height(0){}
26         Matrix(int width, int height):width(width), height(height){
27             p = new T[width * height];
28         }
29         T* operator [](int pos){
30             return p + pos * width;
31         }
32 };
33 
34 int n;
35 Matrix<int>    hf;
36 int lx, ly;
37 
38 inline void init(){
39     readInteger(n);
40     hf = Matrix<int>(n + 1, n + 1);
41 }
42 
43 inline void solve(){
44     memset(hf.p, 0, sizeof(int) * (n + 1) * (n + 1));
45     hf[1][n / 2 + 1] = 1;
46     lx = 1, ly = n / 2 + 1;
47     for(int k = 2; k <= n * n; k++){
48         if(lx == 1 && ly != n){
49             lx = n;
50             ly++;
51         }else if(ly == n && lx != 1){
52             ly = 1;
53             lx--;
54         }else if(ly == n && lx == 1){
55             lx++;
56         }else if(hf[lx - 1][ly + 1] == 0){
57             lx--;
58             ly++;
59         }else{
60             lx++;
61         }
62         hf[lx][ly] = k;
63     }
64     for(int i = 1; i <= n; i++){
65         for(int j = 1; j <= n; j++){
66             printf("%d ", hf[i][j]);
67         }
68         putchar('\n');
69     }
70 }
71 
72 int main(){
73     freopen("magic.in", "r", stdin);
74     freopen("magic.out", "w", stdout);
75     init();
76     solve();
77     return 0;
78 }


  直接Tarjan,当然也可以直接用深搜(貌似要比Tarjan快一点,其实思路还是差不多的)

Code(Tarjan)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cctype>
  4 #include<cstring>
  5 #include<map>
  6 #include<set>
  7 #include<stack>
  8 #include<queue>
  9 #include<vector>
 10 #include<algorithm>
 11 using namespace std;
 12 typedef bool boolean;
 13 template<typename T>
 14 inline void readInteger(T& u){
 15     char x;
 16     while(!isdigit((x = getchar())));
 17     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
 18     ungetc(x, stdin);
 19 }
 20 #define smin(a, b) a = min(a, b)
 21 
 22 typedef class Edge{
 23     public:
 24         int next;
 25         int end;
 26         Edge(const int next = 0, const int end = 0):next(next), end(end){}
 27 }Edge;
 28 
 29 typedef class MapManager{
 30     public:
 31         int *h;
 32         Edge *edge;
 33         int ce;
 34         MapManager():h(NULL), edge(NULL), ce(0){}
 35         MapManager(int points, int edges):ce(0){
 36             h = new int[(const int)(points + 1)];
 37             edge = new Edge[(const int)(edges + 1)];
 38             memset(h, 0, sizeof(int) * (points + 1)); 
 39         }
 40         inline void addEdge(int from, int end){
 41             edge[++ce] = Edge(h[from], end);
 42             h[from] = ce; 
 43         }
 44 }MapManager;
 45 
 46 #define m_begin(g, i) (g).h[(i)]
 47 #define m_next(g, i) (g).edge[(i)].next
 48 #define m_end(g, i)    (g).edge[(i)].end
 49 
 50 int *uf;
 51 int cn;
 52 stack<int> s;
 53 int *visitID;
 54 int *exitID;
 55 boolean* visited;
 56 boolean* inStack;
 57 MapManager g;
 58 int result;
 59 
 60 inline void getSonMap(int end){
 61     int counter = 1;
 62     int buf = s.top();
 63     int first = buf;
 64     s.pop();
 65     inStack[buf] = false;
 66     while(buf != end){
 67         buf = s.top();
 68         s.pop();
 69         inStack[buf] = false;
 70         uf[buf] = first;
 71         counter++;
 72     }
 73     if(counter > 1)
 74         smin(result, counter);
 75 }
 76 
 77 void Tarjan(int node){
 78     visitID[node] = exitID[node] = ++cn;
 79     visited[node] = true;
 80     inStack[node] = true;
 81     s.push(node);
 82     for(int i = m_begin(g, node); i != 0; i = m_next(g, i)){
 83         int& e = m_end(g, i);
 84         if(!visited[e]){
 85             Tarjan(e);
 86             exitID[node] = min(exitID[node], exitID[e]);
 87         }else if(inStack[e]){
 88             exitID[node] = min(exitID[node], visitID[e]);
 89         }
 90     }
 91     if(exitID[node] == visitID[node]){
 92         getSonMap(node);
 93     }
 94 }
 95 
 96 int n;
 97 
 98 inline void init(){
 99     readInteger(n);
100     g = MapManager(n, n);
101     uf = new int[(const int)(n + 1)];
102     visitID = new int[(const int)(n + 1)];
103     exitID = new int[(const int)(n + 1)];
104     inStack = new boolean[(const int)(n + 1)];
105     visited = new boolean[(const int)(n + 1)];
106     memset(visited, false, sizeof(boolean) * (n + 1));
107     memset(inStack, false, sizeof(boolean) * (n + 1));
108     for(int i = 1, a; i <= n; i++){
109         readInteger(a);
110         uf[i] = i;
111         g.addEdge(i, a);
112     }
113 }
114 
115 inline void solve(){
116     result = 0xfffffff;
117     for(int i = 1; i <= n; i++)
118         if(!visited[i])
119             Tarjan(i);
120     delete[] visitID;
121     delete[] exitID;
122     printf("%d", result);
123 }
124 
125 int main(){
126     freopen("message.in", "r", stdin);
127     freopen("message.out", "w", stdout);
128     init();
129     solve();
130     return 0;
131 }
Tarjan

  dfs的话就记一个访问的时间戳,还要即一个是否在栈中,当时间戳不为初值并且在栈中才说明是环

Code(Dfs)

#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#define smin(a, b) a = min(a, b)
using namespace std;
typedef bool boolean;
template<typename T>
inline void readInteger(T& u){
    char x;
    while(!isdigit((x = getchar())));
    for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    ungetc(x, stdin);
}
int n;
int timec;
int* next;
int* rank;
boolean* inStack;
int result = 0xfffffff;
void find(int node){
    if(rank[node] != -1 && inStack[node]){
        smin(result, ++timec - rank[node]);
        return;
    }
    if(rank[node] != - 1)    return;
    inStack[node] = true;
    rank[node] = ++timec;
    find(next[node]);
    inStack[node] = false;
}
int main(){
    freopen("message.in", "r", stdin);
    freopen("message.out", "w", stdout);
    readInteger(n);
    next = new int[(const int)(n + 1)];
    rank = new int[(const int)(n + 1)];
    inStack = new boolean[(const int)(n + 1)];
    memset(rank, -1, sizeof(int) * (n + 1));
    for(int i = 1; i <= n; i++){
        readInteger(next[i]);
        inStack[i] = false;
    }
    for(int i = 1; i <= n; i++){
        if(rank[i] == -1)
            find(i);
    }
    printf("%d", result);
    return 0;
}
Dfs


  思路很简单,搜!不过如果对子、三带一都去搜的话很耗时间,也很耗代码,而且它们是可以直接算出来的

稍微贪一下心,把能带走的都带走,而且从多的开始带。但是双王要记住特殊处理

  搜的内容就只包括顺子,只不过注意所有情况都要搜到,因为某些数据顺子即使搜得长,并不是最优的,反

而导致单牌过多。其他都还是没有什么特别坑的细节。

Code

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<map>
 6 #include<set>
 7 #include<queue>
 8 #include<vector>
 9 #include<algorithm>
10 #define smin(a, b) a = min(a, b)
11 using namespace std;
12 typedef bool boolean;
13 template<typename T>
14 inline void readInteger(T& u){
15     char x;
16     while(!isdigit((x = getchar())));
17     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
18     ungetc(x, stdin);
19 }
20 
21 int n;
22 int kase;
23 int key[14] = {0, 12, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
24 int had[16];
25 
26 inline void init(){
27     memset(had, 0, sizeof(had));
28     for(int i = 1, a, b; i <= n; i++){
29         readInteger(a);
30         readInteger(b);
31         if(a == 0) had[13 + b]++;
32         else had[key[a]]++;
33     }
34 }
35 
36 int calc(){
37     int counter[5] = {0, 0, 0, 0, 0};
38     for(int i = 1; i <= 15; i++){
39         if(had[i] > 0){
40             counter[had[i]]++;
41         }
42     }
43     int reter = 0;
44     boolean aFlag = 0;
45     if(had[14] == 1 && had[15] == 1){    
46         aFlag = 1;
47     }
48     while(counter[4] && counter[2] >= 2) reter++, counter[4] -= 1, counter[2] -= 2;
49     while(counter[4] && counter[1] >= 2) reter++, counter[4] -= 1, counter[1] -= 2;
50     while(counter[4] && counter[2]) reter++, counter[4] -= 1, counter[2] -= 1;
51     while(counter[3] && counter[2])    reter++, counter[3] -= 1, counter[2] -= 1;
52     while(counter[3] && counter[1])    reter++, counter[3] -= 1, counter[1] -= 1;
53     if(counter[1] >= 2 && aFlag) counter[1] -= 1;
54     return reter + counter[1] + counter[2] + counter[3] + counter[4];
55 }
56 
57 int result;
58 void search(int last, int times){
59     if(last == 0){
60         smin(result, times);
61         return;
62     }
63     smin(result, times + calc());
64     if(times >= result)    return;
65     //顺子
66     if(last >= 5){
67         for(int p = 3; p >= 1; p--){
68             for(int i = 1; i <= 12; i++){
69                 int k = i;
70                 while(had[k] >= p && k < 13) k++;
71                 if((k - i) * p >= 5){
72                     for(int j = i; j < k; j++){
73                         had[j] -= p;
74                     }
75                     for(int j = k - 1; j >= i; j--){
76                         if((j - i + 1) * p >= 5)
77                             search(last - (j - i + 1) * p, times + 1);
78                         had[j] += p;
79                     }
80                 }    
81             }
82         }
83     }
84 }
85 
86 int main(){
87     freopen("landlords.in", "r", stdin);
88     freopen("landlords.out", "w", stdout);
89     readInteger(kase);
90     readInteger(n);
91     while(kase--){
92         init();
93         result = n;
94         search(n, 0);
95         printf("%d\n", result);
96     }
97     return 0;
98 }

 

  

posted @ 2016-10-17 15:02  阿波罗2003  阅读(280)  评论(0编辑  收藏  举报