zoukankan      html  css  js  c++  java
  • NOIP 2015 day1

    pts:300

    T1: 100

    T2: 100

    T3: 100

    [NOIP2015 提高组] 神奇的幻方

    模拟

    emm,没啥说的

    [NOIP2015 提高组] 信息传递

    图论

    Tarjan 板子

    /*
    work by:Ariel_
    */
    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int N = 2e5 + 5;
    int read(){
        int x = 0,f = 1; char c = getchar();
        while(c < '0'||c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') {x = x*10 + c - '0'; c = getchar();}
        return x*f;
    }
    int n, Ans = 0x3f3f3f3f, dfn[N], low[N], tot, cnt, siz[N], ins[N], st[N], tp, head[N], E;
    struct edge{int v, nxt;}e[N];
    void add_edge(int u, int v) {
       e[++E] = (edge){v, head[u]};
       head[u] = E; 
    }
    void Tarjan(int x) {
       dfn[x] = low[x] = ++tot;
       st[++tp] = x, ins[x] = 1, siz[x] = 1;
       for (int i = head[x]; i; i = e[i].nxt) {
       	    int v = e[i].v;
       	    if(!dfn[v]) {
       	      Tarjan(v);
    		  low[x] = min(low[x], low[v]);	 
    		}
    	   else if(ins[v]) low[x] = min(dfn[v], low[x]); 
       }
       if (low[x] == dfn[x]) {
       	   cnt++;
       	   while(1){
       	   	  int k = st[tp--];
    		  if (k == x) break; siz[cnt]++;
    	   } 
       }
    }  
    int main(){
       n = read();
       for (int i = 1, x; i <= n; i++) x = read(), add_edge(i, x);
       for (int i = 1; i <= n; i++) if (!dfn[i]) Tarjan(i);
       for (int i = 1; i <= cnt; i++) if (siz[i] > 1) Ans = min(Ans, siz[i]);
       printf("%d
    ", Ans);
       return 0;
    }
    

    [NOIP2015 提高组] 斗地主

    爆搜

    /*
    work by:Ariel_
    斗地主大纲 
    */
    //#include <bits/stdc++.h>
    //using namespace std;
    //
    //void work(int stp) {
    //    if(ans > stp) stop;
    //    单顺子, 用个计数器统计顺子牌的数量
    //    for(牌) 
    //    如果某个牌 = 0,计数器就归 0
    //    如果牌数 >= 5 把顺子出出去,然后递归出牌
    //    回溯
    //    双顺子
    //    for (牌)
    //    如果某个牌 < 2,计数器清零
    //    如果牌数 >= 3 把顺子出出去,然后递归出牌
    //    回溯
    //    三顺子
    //    for (牌)
    //    如果某个牌 < 3,计数器清零
    //    如果牌数 >= 2, 计数器清零
    //    带牌
    //    三带一,二 
    //    for (牌)
    //      如果某个牌 == 3
    //        P[某个牌] -= 3; 
    //         for (牌) 
    //           如果某个牌 >= 1
    //         出牌
    //         回溯
    //         for (牌)//三带二 
    //           如果某个牌 >= 2
    //         出牌
    //         回溯 
    //       P[某个牌] += 3
    //    四张牌 
    //    可以选择出三张,和上面一个样
    //    四带二/二对
    //    P[牌] -= 4 
    //    for (牌) 
    //      P[某张牌] >= 1 带牌 1
    //      for (牌) 
    //        P[某张牌] >= 1 带牌 2
    //        回溯
    //      回溯 
    //    for (牌)
    //     P[某张牌] >= 2 带牌 1
    //      for (牌) 
    //        P[某张牌] >= 2 带牌 2
    //        回溯
    //      回溯 
    //    P[牌] += 4;(回溯)
    //    for (牌) 如果某个牌有剩余,直接都出出去,stp++;
    //    ans = min(ans, stp); 
    //}
    //int main(){
    //   //T,n 
    //   //读入牌,用数组统计每种牌的个数,大王小王用 15 表示, A 用 14 表示(正常斗地主插牌方式) 
    //   //开始搜索出牌 work(step)  
    //}
    /*
    work by:Ariel_
    10:00 过了样例 睡觉 
    */
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <algorithm>
    using namespace std;
    const int N = 30;
    int read(){
        int x = 0,f = 1; char c = getchar();
        while(c < '0'||c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') {x = x*10 + c - '0'; c = getchar();}
        return x*f;
    }
    int T, n, P[N], Ans = 0x3f3f3f3f;
    void clear(){memset(P, 0, sizeof P), Ans = 0x3f3f3f3f;}
    void work(int stp) {
        if (stp >= Ans) return ;
        int tot = 0;
    	for (int i = 3; i <= 14; i++) {//单顺子 
            if (!P[i]) tot = 0;
            else {
               tot++;
    		   if (tot >= 5){
    		   	  for (int j = i; j >= i - tot + 1; j--) P[j]--;
    		      work(stp + 1);
    		      for (int j = i; j >= i - tot + 1; j--) P[j]++;
    		   } 
    		}  
    	}
    	tot = 0;
    	for (int i = 3; i <= 14; i++) {//双顺子 
    	    if (P[i] < 2) tot = 0;
    		else {
    		   tot++;
    		   if (tot >= 3) {
    		   	 for (int j = i; j >= i - tot + 1; j--) P[j] -= 2;
    		   	 work (stp + 1);
    		   	 for (int j = i; j >= i - tot + 1; j--) P[j] += 2;
    		   }
    		}	
    	}
       tot = 0;
       for (int i = 3; i <= 14; i++) {//三顺子 
       	  if (P[i] < 3) tot = 0;
       	  else {
       	     tot++;
    	     if (tot >= 2) {
    	        for (int j = i; j >= i - tot + 1; j--) P[j] -= 3;
    	        work(stp + 1);
    	        for (int j = i; j >= i - tot + 1; j--) P[j] += 3;
    		 }	 
    	  }  
       }
       for (int i = 2; i <= 14; i++) {//三带一/二 
       	   if (P[i] <= 3) {
       	   	  if (P[i] <= 2) continue;
       	   	  P[i] -= 3;
       	   	  for (int j = 2; j <= 15; j++) {
       	   	     if (P[j] <= 0 || j == i) continue;
    		     P[j]--, work(stp + 1), P[j]++;	
    		   }
    		  for (int j = 2; j <= 14; j++) {
    		  	  if (P[j] < 2 || j == i) continue;
    		  	  P[j] -= 2, work(stp + 1), P[j] += 2;
    		  }
    		  P[i] += 3;
    	   }
    	   else {
    	   	  P[i] -= 3;
    	 	  for (int j = 2; j <= 15; j++) { 
      	 	     if (!P[j]|| j == i) continue;
      	 	       P[j]--, work(stp + 1), P[j]++;	
    			}
    		  for (int j = 2; j <= 14; j++){ 
    		   	  if (P[j] <= 1|| j == i) continue;
    		   	  P[j] -= 2, work(stp + 1), P[j] += 2;
    		    }
    		    P[i] += 3, P[i] -= 4;//四带二 
    		  for (int j = 2; j <= 15; j++) {
    		  	 if (!P[j]|| i == j) continue;
    		  	 P[j]--;
    			 for (int k = 2; k <= 15; k++) {
    			 	if (!P[k] || k == j) continue;
    			 	P[k]--, work(stp + 1), P[k]++;
    			 }
    			 P[j]++; 
    		  }
    		  for (int j = 2; j <= 14; j++) {
    		  	 if (P[j] <= 1 || i == j) continue;
    		  	 P[j] -= 2;
    		  	 for (int k = 2; k <= 14; k++) {
    		  	      if (P[k] <= 1 || k == j) continue;
    				  P[k] -= 2, work(stp + 1), P[k] += 2; 	 
    			   }
    			 P[j] += 2;
    		  }
    	     P[i] += 4;	  
    	   }
       }
       for (int i = 2;i <= 15; i++)  if(P[i]) stp++; 
       Ans = min(Ans, stp);
    }
    int main(){
       T = read(), n = read();
       while(T--) {
       	  clear();
       	  for (int i = 1, num, fag; i <= n; i++) {
       	  	  num = read(), fag = read(); 
       	  	  if (num == 1) P[14]++;
       	  	  else if(!num) P[15]++;
       	  	  else P[num]++;
    	  }
    	  work(0);
    	  printf("%d
    ", Ans);
       }
       return 0;
    }
    
  • 相关阅读:
    flex学习小结
    Frameset框架
    表格的增删改
    【实践】用 js 封装java shuffle函数(打乱数组下标方法)
    【实践】js封装 jq siblings 方法
    【笔记】js原生方法 在元素外部或内部实现添加元素功能(类似jq 的 insert 和 append)
    【实践】js实现windows系统日历
    【实践】用for-in 循环实现三联联动
    【笔记】js Array.prototype.slice.call(arguments) 将函数的参数转换为数组方法的见解
    【笔记】js Function类型 内部方法callee
  • 原文地址:https://www.cnblogs.com/Arielzz/p/14906780.html
Copyright © 2011-2022 走看看