• 2016.6.8测试


    1. ly的农场
    【题目描述】
    在农夫ly的农场里,有好多好多的奶牛,但是由于ly喂养得太好了,奶牛们越来越懒了,导致ly不得不采取些措施:要求它们每天早上晨跑,从A农场跑到B农场。从A农场到B农场中有n–2个路口,分别标上号,A农场为1号,B农场为n号,路口分别为2..n–1号,从A农场到B农场有很多条路径可以到达,而ly发现有的路口是必须经过的,即每条路径都经过的路口,ly要把它们记录下来,这样ly就可以先到那个路口,观察奶牛们有没有偷懒,而你的任务就是找出所有必经路口。
    【输入文件】
    第一行两个数n,m。
    接下来m行,每行两个数u和v,表示路口u和v之间有路径直达。
    输入数据保证必经路口一定存在,并且每个路口都和A,B农场直接或间接连通。
    【输出文件】
    第一行一个数m,表示必经路口数目。
    接下来m行,按从小到大的顺序依次输出每个必经路口的编号。(不包括起点,终点)

    【样例输入】
    6 6
    1 2
    2 4
    2 3
    3 5
    4 5
    5 6
    【样例输出】
    2
    2
    5
    【数据范围】
    对于30%的数据,n ≤ 100,m ≤ 1000。
    对于100%的数据,n ≤ 2000,m ≤ 8000。

    正解:暴力。。。

    解题报告:

      考场上面打的是tarjan,实际上举得出反例。其实直接暴力枚举就可以了,每次遍历全图,看不经过某点是否可以到达终点。

     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #include <stack>
    14 #ifdef WIN32   
    15 #define OT "%I64d"
    16 #else
    17 #define OT "%lld"
    18 #endif
    19 using namespace std;
    20 typedef long long LL;
    21 const int MAXN = 2011;
    22 const int MAXM = 16011;
    23 int n,m,ecnt,now;
    24 int first[MAXN],next[MAXM],to[MAXM];
    25 bool vis[MAXN];
    26 bool ok;
    27 int dui[MAXN],cnt;
    28 
    29 inline int getint()
    30 {
    31     int w=0,q=0;
    32     char c=getchar();
    33     while((c<'0' || c>'9') && c!='-') c=getchar();
    34     if (c=='-')  q=1, c=getchar();
    35     while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    36     return q ? -w : w;
    37 }
    38 
    39 inline void link(int x,int y){
    40     next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; 
    41     next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x;
    42 }
    43 
    44 inline void dfs(int x){
    45     if(x==n) { ok=true; return ;}
    46     vis[x]=1;
    47     for(int i=first[x];i;i=next[i]){
    48     int v=to[i];
    49     if(!vis[v] && v!=now) dfs(v);
    50     if(ok) return ;
    51     }
    52 }
    53 
    54 inline void solve(){
    55     n=getint(); m=getint();
    56     int x,y;
    57     for(int i=1;i<=m;i++) {
    58     x=getint(); y=getint();
    59     link(x,y);
    60     }
    61 
    62     for(int i=2;i<n;i++) {
    63     now=i; ok=false;
    64     memset(vis,0,sizeof(vis));
    65     dfs(1);
    66     if(!ok) dui[++cnt]=i;
    67     }
    68 
    69     printf("%d
    ",cnt);
    70     for(int i=1;i<=cnt;i++) {
    71     printf("%d
    ",dui[i]);
    72     }
    73 }
    74 
    75 int main()
    76 {
    77     solve();
    78     return 0;
    79 }

    2.xqz的难题
    【题目描述】
    xqz同学最近迷上了位运算,因为他天才般的头脑,题目都过于简单了。不过他今天ms状态不怎么好,被下面这道题打击到了,于是去寻找正在堕落的ld。题目如下:
    给定一个数列,设计一个算法支持以下操作:
    1. 插入一个数到数列的最后。
    2. 在数列中找到一个值为k的数,将它从数列中删去。(数据保证数列中存在值为k的数,若有多个K值,任意删除1外)
    3. 求值在L到R间的所有数依次进行xor的值。如果只有一个数满足条件,输出此数。
    如果没有数满足,输出0。
    (扫盲:xor在电脑的计算器里有,例如:7 xor 6 xor 3 = 2)
    数列初始时为空。
    【输入文件】
    第一行,一个数m,表示操作的个数。
    接下来有m行,对于每一行,首先一个数q:
    若q=1,则后面一个数k(k ≤106),表示将k插入到数列的最后。
    若q=2,则后面一个数k,表示将一个值为k的数删去。
    若q=3,则后面两个数L和R,表示输出值在L到R间的所有数依次进行xor的值。

    【输出文件】
    对于每一个q=3的操作输出答案,每行一个数。
    【样例输入】
    5
    1 5
    1 6
    3 1 10
    2 5
    3 1 8
    【样例输出】
    3
    6
    【数据范围】
    对于30%的数据,m ≤ 2000。
    对于100%的数据,m ≤ 100000,答案 ≤ 2^31 - 1。

    正解:树状数组

    解题报告:

      考场上又智障了。我的做法是先离线再离散化,然后树状数组,然而写萎了。实际上直接树状数组不用任何优化就可以了,毕竟只有10的6次方。。。

      异或有很多神奇的性质,这道题就体现了这一点。

      代码又短又快。

     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #ifdef WIN32   
    14 #define OT "%I64d"
    15 #else
    16 #define OT "%lld"
    17 #endif
    18 using namespace std;
    19 typedef long long LL;
    20 const int MAXM = 1000011;
    21 int a[MAXM];
    22 int n=1000000,m;
    23 
    24 inline int getint()
    25 {
    26        int w=0,q=0;
    27        char c=getchar();
    28        while((c<'0' || c>'9') && c!='-') c=getchar();
    29        if (c=='-')  q=1, c=getchar();
    30        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    31        return q ? -w : w;
    32 }
    33 
    34 inline void update(int x){
    35     int val=x;
    36     while(x<=n) {
    37     a[x]^=val;
    38     x+=( x&(-x) );
    39     }
    40 }
    41 
    42 inline int query(int x){
    43     int total=0;
    44     while(x>0) {
    45     total^=a[x];
    46     x-=( x&(-x) );
    47     }
    48     return total;
    49 }
    50 
    51 inline void solve(){
    52     m=getint();
    53     int x,y; 
    54     for(int i=1;i<=m;i++) {
    55     int ljh=getint();
    56     if(ljh==3) {
    57         x=getint();y=getint();
    58         printf("%d
    ",query(y)^query(x-1));
    59     }
    60     else{
    61         x=getint();
    62         update(x);
    63     }
    64     }
    65 }
    66 
    67 int main()
    68 {
    69   solve();
    70   return 0;
    71 }

    3.ld的棋盘
    【题目描述】
    (紧接上一题)“题目beng不难类!”xqz找到了ld,结果遭到了强烈的鄙视…怎么办类?xqz灵光一闪,拿出新买的一个“#”形棋盘,上面有24个格子(如下图)。这些格子上面
    有1,2,3三种数字,且每种数字有8格。一开始,这些格子上的数字是随机分布的。ld的任务是移动这些格子使得中间8个格子的数字相同。有8种移动方式,分别标记为A到H,可以理解为拉动4条链,如图的变换为“AC”。问至少需要多少次拉动,才能从初始状态到达目标状态?(保证数据有解)ld顿时木了,于是求助作为OI高手的你。

    (图略)

    【输入文件】
    有多组数据。每组数据包含一行,24个数字,表示从上到下从左到右表示棋盘上的数字。以0结束数据。(友情提示:请注意空间)
    【输出文件】

    每组数据一行,输出最少移动次数。
    【样例输入】
    1 1 1 1 3 2 3 2 3 1 3 2 2 3 1 2 2 2 3 1 2 1 3 3
    1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3
    0
    【样例输出】
    2
    4
    【数据范围】
    对于30%的数据,最大步数 ≤ 7,数据组数 ≤ 10。
    对于60%的数据,最大步数 ≤ 12,数据组数 ≤ 20。
    对于100%的数据,最大步数 ≤ 12,数据组数 ≤ 30。

    正解:搜索

    解题报告:

      北大信息学夏令营一试第一题,才从北京回来,今天考试又考到了这道题。。。

      只不过这道题稍稍弱化了一点。

      就直接搜索,迭代加深搜索,确定搜索次数上界,进行搜索。

      首先看一下中间的八个格子变成哪个数,1或者2或者3,3次枚举(剪枝:选择需要移动次数最少的)。

      确定完变成谁之后就枚举几种移动方式(字母),往下dfs。

      这样的话还是会TLE一个点,我们考虑避免一种情况,上一层往上移动,这一层又往下移动,这显然是没必要的,剪掉,就可以AC了。

      这题的翻版是POJ2286。

      1 //It is made by jump~
      2 #include <iostream>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <cstdio>
      6 #include <cmath>
      7 #include <algorithm>
      8 #include <ctime>
      9 #include <vector>
     10 #include <queue>
     11 #include <map>
     12 #include <set>
     13 #ifdef WIN32   
     14 #define OT "%I64d"
     15 #else
     16 #define OT "%lld"
     17 #endif
     18 using namespace std;
     19 typedef long long LL;
     20 const int MAXC = 1011;
     21 int daan;
     22 /*
     23        0     1
     24        2     3
     25 4  5   6     7  8  9 10
     26       11    12
     27 13 14 15 16 17 18 19
     28       20    21
     29       22    23  */
     30 int mp[12][12]={{0,2,6,11,15,20,22}/*A*/,{1,3,8,12,17,21,23}/*B*/,{10,9,8,7,6,5,4}/*C*/,{19,18,17,16,15,14,13}/*D*/};
     31 int fan[12] = {5,4,7,6,1,0,3,2};
     32 int zhong[12] = {6,7,8,11,12,15,16,17};//中心的编号
     33 int a[45];
     34 
     35 inline int getint()
     36 {
     37     int w=0,q=0;
     38     char c=getchar();
     39     while((c<'0' || c>'9') && c!='-') c=getchar();
     40     if (c=='-')  q=1, c=getchar();
     41     while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
     42     return q ? -w : w;
     43 }
     44 
     45 inline bool already() {
     46     for(int i=0;i<=7;i++) if (a[zhong[i]]!=a[zhong[0]]) return false;
     47     return true;
     48 }
     49 
     50 inline int coun(int check) {
     51     int jishu=0;
     52     for(int i=0;i<8;i++)  if(a[zhong[i]]!=check) jishu++;
     53     return jishu;
     54 }
     55 
     56 inline int gu() {
     57     int ljh=coun(1);
     58     for(int i=2;i<=3;i++) //分别放1、2、3
     59     ljh=min(coun(i),ljh);
     60     return ljh;
     61 }
     62 
     63 inline void move(int x) {//往指定方向拉动一格
     64     int cun=a[mp[x][0]];
     65     for(int i=0;i<6;i++) a[mp[x][i]]=a[mp[x][i+1]];
     66     a[mp[x][6]]=cun;
     67 }
     68 
     69 inline bool dfs(int d,int maxd,int last) {
     70     if(already()) return true;
     71 
     72     if(d+gu()>maxd) return false;//超过上界
     73 
     74     for(int i=0;i<8;i++) {
     75     if(last==fan[i]) continue;
     76     move(i);
     77     if(dfs(d+1,maxd,i)) return true;
     78     move(fan[i]);//还原
     79     }
     80 
     81     return false;
     82 }
     83 
     84 inline void init(){
     85     fan[10]=-1;
     86     for(int i=4;i<=7;i++) 
     87     for(int j=0;j<=6;j++) 
     88         mp[i][j]=mp[fan[i]][6-j];
     89 }
     90 
     91 inline void solve(){
     92     init();
     93     int xx;
     94     while(scanf("%d",&xx)!=EOF && xx) {
     95     a[0]=xx; for(int i=1;i<=23;i++) scanf("%d",&a[i]);
     96     if(already())  printf("0
    ");       
     97         else {
     98         daan=1;
     99         for(;;daan++)
    100         if(dfs(0,daan,10))  break;
    101     }
    102     printf("%d
    ",daan);
    103     }
    104 }
    105 
    106 int main()
    107 {
    108     solve();
    109     return 0;
    110 }

      

    4.jx的游戏
    【题目描述】
    jx和ld一样,都在堕落……他现在正沉迷于一个国产数字游戏中。这个游戏看似简单,jx在研究了许多天看了许多次Game over的画面后却发觉,原来在简单的规则下想要赢得这个游戏并不那么容易。不过他发现了这个问题的简化版,即给定一个数列,找出1个连续数列使其和最大。但其本身的问题却很难解决:给定一个数列,找出3个无交集的连续数列使其和最大。显然,你的任务是解决这个原问题,好胜的jx很希望你能帮他解决这个问题赢得这个Game。
    【输入文件】
    第一行一个数n,表示数列长度。
    接下来有n行,每行一个数,第i行为第i个数。
    【输出文件】
    仅有一个数,表示最大和。
    【样例输入】
    10
    -1
    2
    3
    -4
    0
    1
    -6
    -1
    1
    -2

    【样例输出】
    7
    【数据范围】
    数列是非空数列且长度大于等于3
    对于30%的数据,n ≤ 200。
    对于60%的数据,n ≤ 2000。
    对于100%的数据,n ≤ 1000000,答案 ≤ 2^31 - 1。

    正解:DP

    解题报告:

      考场上没什么时间做这道题了。一眼秒题:DP。

      短时间内没有设计出状态。考完之后听llg的“满口鬼话”,听懂了这道题的状态。

      f[i][j][0、1]表示处理到第i个数,前i-1个数可以分成j块(j<=3),第i个数选或者不选的最大值   

      丧病出题人卡空间,滚动一下数组就可以了。

      转移还是很好想到的,O(1)转移,轻松AC。

     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #ifdef WIN32   
    14 #define OT "%I64d"
    15 #else
    16 #define OT "%lld"
    17 #endif
    18 using namespace std;
    19 typedef long long LL;
    20 const int MAXN = 1000011;
    21 int n,ans;
    22 int f[2][4][2];
    23 
    24 inline int getint()
    25 {
    26        int w=0,q=0;
    27        char c=getchar();
    28        while((c<'0' || c>'9') && c!='-') c=getchar();
    29        if (c=='-')  q=1, c=getchar();
    30        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    31        return q ? -w : w;
    32 }
    33 
    34 int main()
    35 {
    36   n=getint();
    37 
    38   int jilu=0;
    39   for(int i=1;i<=n;i++) {
    40       jilu=jilu^1;
    41       int x=getint();
    42       f[jilu][1][0]=max(f[!jilu][1][0],f[!jilu][1][1]);
    43       f[jilu][1][1]=x+max(0,f[!jilu][1][1]);
    44 
    45       if(i>=2) {
    46       f[jilu][2][0]=max(f[!jilu][2][0],f[!jilu][2][1]);
    47       f[jilu][2][1]=max(f[!jilu][2][1],max(f[!jilu][1][1],f[!jilu][1][0]))+x;
    48       }
    49 
    50       if(i>=3) {
    51       f[jilu][3][0]=max(f[!jilu][3][0],f[!jilu][3][1]);
    52       f[jilu][3][1]=max(f[!jilu][3][1],max(f[!jilu][2][1],f[!jilu][2][0]))+x;
    53       }
    54 
    55       ans=max(f[jilu][3][0],f[jilu][3][1]);
    56   }
    57 
    58   printf("%d",ans);
    59   return 0;
    60 }
  • 相关阅读:
    SAP 盘盈盘亏移动类型701&702 Vs 711&712
    SAP MM里的ERS功能不适用于供应商寄售采购模式
    Docker overlay2占用大量磁盘空间解决办法
    pytorch 文本多分类
    Python调试输出变量一部分变成了省略号
    Python sklearn.externals中的joblib导入失败
    Python:SyntaxError:(unicode error) 'unicodeescape' codec can't decode bytes in pos
    dotnetCampus.UITest.WPF 一个支持中文用例的界面单元测试框架
    Introduction to Robotics Toolbox
    CUDA application design and development
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5570195.html
Copyright © 2020-2023  润新知