• jzoj C组 2017.1.15比赛


    第一题

    题目描述

    小x有一个由n个整数组成的数列。他现在可以任意交换数列中两个相邻的元素。小x想知道,能否通过一些操作,使得任意两个相邻的元素不同。

    输入

    第一行一个整数t,表示测试数据的组数。

    每组数据第一行包含一个整数n,表示数列中元素的个数。第二行包含n个整数a1,a2,…,an,表示数列中元素的初始状态。

    输出

    输出t行,对于第i组测试数据,如果小x能够得到他所想要的序列,输出“YES”,否则输出“NO”(不包含引号)。

    样例输入

    3

    1

    1

    3

    1 1 2

    4

    7 7 7 7

    样例输出

    YES

    YES

    NO

    数据范围限制

    【数据范围】

    对于100%的数据:1<=t<=100,1<=n<=100,1<=ai<=1000。


    找到每种元素的个数,如果这个元素的个数大于(n+1) div 2就输出NO,否则输出YES


    代码如下:

    var  bool:boolean;
         t,i,j,n,k,max,min:longint;
         a:array[1..1000]of longint;
    
    begin
      assign(input,'permutation.in');
      assign(output,'permutation.out');
      reset(input);
      rewrite(output);
      readln(t);
      for k:=1 to t do
        begin
          fillchar(a,sizeof(a),#0);
          readln(n);
          min:=1001;
          for i:=1 to n do
            begin
              read(j);
              inc(a[j]);
              if j>max then max:=j;
              if j<min then min:=j;
            end;
          bool:=false;
          for i:=min to max do
            begin
              if a[i]>(n+1)div 2 then
                begin
                  bool:=true;
                  break;
                end;
            end;
          if bool then writeln('NO')
                 else writeln('YES');
        end;
      close(input);
      close(output);
    end.

    第二题

    题目描述

    这里写图片描述

    输入

    第一行两个用空格分开的整数n和m,分别表示P(x)和Q(x)的最高项指数。

    第二行包含n+1用空格分开的整数,a0,a1,…,an,表示P(x)的每项系数。

    第三行包含m+1用空格分开的整数,b0,b1,…,bm,表示Q(x)的每项系数。

    输出

    如果最后得到的极限为正无穷,输出“Infinity”;

    如果为负无穷,输出“-Infinity”;

    如果最后得到的极限为0,输出“0/1”;

    否则,输出一个最简分数,为所得极限的值,以“p/q”的形式,p为分子,q为分母。

    样例输入

    limit.in1:

    2 1

    1 1 1

    2 5

    limit.in2:

    1 0

    -1 3

    2

    limit.in3:

    0 1

    1

    1 0

    limit.in4:

    2 2

    2 1 6

    4 5 -7

    limit.in5:

    1 1

    9 0

    -5 2

    样例输出

    limit.out1:

    Infinity

    limit.out2:

    -Infinity

    limit.out3:

    0/1

    limit.out4:

    1/2

    limit.out5:

    -9/5

    数据范围限制

    对于100%的数据:0<=n,m<=100,|ai|,|bi|<10^5。


    看数据可以发现,数值是由两行的第一个数决定的。
    如果一正一负则输出-号
    如果n>m则输出Infinity
    如果n=m则将a[1]和b[1]约分后输出,要记得输出符号
    如果n小于m则输出0/1


    代码如下:

    var   n,m,x,y:longint;
          bool1,bool2:boolean;
    
    procedure yue;
    var i:longint;
    begin
      for i:=2 to x do
        if (x mod i=0)and(y mod i=0) then
          begin
            x:=x div i;
            y:=y div i;
          end;
    end;
    
    begin
      assign(input,'limit.in');
      assign(output,'limit.out');
      reset(input);
      rewrite(output);
      readln(n,m);
      readln(x);
      readln(y);
      if x<0 then bool1:=true else bool1:=false;
      if y<0 then bool2:=true else bool2:=false;
      x:=abs(x); y:=abs(y);
      if n>m then
        begin
          if (bool1=true)and(bool2=false)or(bool1=false)and(bool2=true) then write('-');
          write('Infinity');
        end
      else
        if n=m then
          begin
            yue;
            if (bool1=true)and(bool2=false)or(bool1=false)and(bool2=true) then write('-');
            write(x,'/',y);
          end
        else write(0,'/',1);
      close(input);
      close(output);
    end.

    第三题

    题目描述

    小x有两个长度均为n的字符串s和w。小x认为s和w是不可比较的,当存在i和j (0<=i,j<=n),si>wi并且sj< wj。si表示字符串s中的第i个元素,相似的,wj表示字符串w中第j个元素。

    字符串模板由数字和问号“?”构成,“?”并不会成对出现。

    小x现在有两个长度为n的字符串模板。每个问号可以填不同的数或相同的数,小x想要计算填数的方案数,使得这两个字符串不可比较。最终得到的字符串可以包含前导零。

    帮助小x计算出方案数除以1000000007的余数。

    输入

    第一行一个整数n,表示字符串模板的长度。

    第二、第三行,每行包含一个长度为n的字符串模板。

    输出

    一行一个整数,方案数除以1000000007的余数。

    样例输入

    strings.in1:

    2

    90

    09

    strings.in2:

    2

    11

    55

    strings.in3:

    5

    ?????

    ?????

    样例输出

    strings.out1:

    1

    strings.out2:

    0

    strings.out3:

    993531194

    数据范围限制

    对于20%的数据 :1<=n<=5

    对于50%的数据: 1<=n<=25

    对于100%的数据: 1<=n<=10^5


    这题是分五种情况去判断
    ①如果st1[i]和st2[i]都是’?’则a[i,1]:=a[i-1,1]*55(即0~9,1~9……9)
    a[i,2]同上
    总方案数ans*100
    ②如果st1[i]=’?’和st2[i]<>’?’a[i,1]:=a[i-1,1]*(10-st2[i] (数值))
    a[i,2]:=a[i,2-1]*(st2[i] (数值)+1) ans:=ans *10
    ③如果st1[i]<>’?’和st2[i]=’?’,其原理如上
    ④如果st1[i]<>’?’和st2[i]<>’?’ 而且st1[i]>st2[i]则将a[i,1]:=a[i-1,1]
    ⑤如果st1[i]<>’?’和st2[i]<>’?’ 而且st1[i]

    const mod1=1000000007;
    
    var  n,i,x,ans,l,y:longint;
         st1,st2:ansistring;
         f:array[0..100000,1..2]of longint;
    
    begin
      assign(input,'strings.in');
      assign(output,'strings.out');
      reset(input);
      rewrite(output);
      readln(n);
      f[0,1]:=1; f[0,2]:=1;
      readln(st1);
      readln(st2);
      ans:=1;
      y:=1;
      l:=0;
      for i:=1 to n do
        if (st1[i]=st2[i])and(st1[i]='?') then
          begin
            f[i,1]:=(int64(f[i-1,1])*55) mod mod1;
            f[i,2]:=(int64(f[i-1,2])*55) mod mod1;
            ans:=(int64(ans)*10*10) mod mod1;
            inc(l);
          end
        else
          if (st1[i]='?') then
            begin
              val(st2[i],x);
              f[i,1]:=(int64(f[i-1,1])*(10-x)) mod mod1;
              f[i,2]:=(int64(f[i-1,2])*(x+1)) mod mod1;
              ans:=(int64(ans)*10) mod mod1;
            end
          else
            if st2[i]='?' then
              begin
                val(st1[i],x);
                f[i,1]:=(int64(f[i-1,1])*(x+1)) mod mod1;
                f[i,2]:=(int64(f[i-1,2])*(10-x)) mod mod1;
                ans:=(int64(ans)*10) mod mod1;
              end
            else
              if st1[i]>st2[i] then f[i,1]:=f[i-1,1] else f[i,2]:=f[i-1,2];
      ans:=ans-f[n,1]-f[n,2];
      if (f[n,1]>0)and(f[n,2]>0) then
        begin
          for i:=1 to l do y:=(int64(y)*10) mod mod1;
          ans:=ans+y;
        end;
      if ans<0 then ans:=ans+mod1;
      write(ans);
      close(input);
      close(output);
    end.

    第四题

    题目描述

      小x有一个由n个顶点构成的加权有向图,这张图中,任意两个顶点之间的都有两条方向不同的边。小x很喜欢玩图,现在他发明了一个新的游戏:
    
      这个游戏共有n步。
    
      在第i步时,小x把第xi个点从图中删除,同时删除所有与xi相连的边,包括xi的入边和出边。
    
      每步操作进行前,小x想知道所有剩余顶点之间的最短路径的长度之和,最短路径可以通过任何剩余的顶点。换句话说,我们定义d(i,v,u)是在删除顶点xi之前,顶点v到顶点u的最短路径。
    

    输入

    第一行包含一个整数n,表示图的顶点数。

    接下来n行,每行n个整数,第i行第j个元素aij表示顶点i到顶点j的边的权值。

    最后一行,包含n个不同的整数:x1,x2,…,xn(1<=xi<=n),表示小x删的顶点。

    输出

    一行用1个空格分开的n个整数,第i个数表示在第i步前所求的值。行末没有多余的空格。

    样例输入

    shortest.in1:

    1

    0

    1

    shortest.in2:

    2

    0 5

    4 0

    1 2

    shortest.in3:

    4

    0 3 1 1

    6 0 400 1

    2 4 0 1

    1 1 1 0

    4 1 2 3

    样例输出

    shortest.out1:

    0

    shortest.out2:

    9 0

    shortest.out3:

    17 23 404 0

    数据范围限制

    对于30%的数据:1<=n<=50

    对于70%的数据:1<=n<=100

    对于100%的数据:1<=n<=500,1<=xi<=n,1<=aij<=10^5,aii=0


    这题如果直接弗洛伊德可能数值会有很多重复
    所以
    我们从最后删掉的点一直往会搜到没有删点
    每次增加一个点,再判断这个点加进来有没有比原来的最短路径还短的路径,更新数值。直到没有删点。


    代码如下:

    var  n,i,j,k:longint;
         a:array[0..505,0..505]of longint;
         b,ans:array[0..1010]of longint;
    begin
      assign(input,'shortest.in');
      assign(output,'shortest.out');
      reset(input);
      rewrite(output);
      readln(n);
      for i:=1 to n do
        begin
          for j:=1 to n do read(a[i,j]);
          readln;
        end;
      for i:=1 to n do read(b[i]);
      for k:=n downto 1 do
        begin
          for i:=1 to n do
            for j:=1 to n do
              begin
                if a[b[i],b[k]]+a[b[k],b[j]]<a[b[i],b[j]] then a[b[i],b[j]]:=a[b[i],b[k]]+a[b[k],b[j]];
                if (i>=k)and(j>=k) then ans[k]:=ans[k]+a[b[i],b[j]];
              end;
        end;
      for i:=1 to n do write(ans[i],' ');
      close(input);
      close(output);
    end.
  • 相关阅读:
    *VC编程规范
    C++的va_start() va_end()函数应用(转)
    * C++类的分解,抽象类与纯虚函数的需要性
    *C++中的回调
    *C++中使用接口
    C++模版使用
    *获取mac地址的方法
    *数字——字符之间的转换(转)
    eclipse雕虫小技一:eclipse打开文件目录
    Hibernate升级后注解方式的对象关系映射
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8412447.html
Copyright © 2020-2023  润新知