zoukankan      html  css  js  c++  java
  • FJUTOJ-周赛2016-12-16

    注:fjutoj基本每周都有一次周赛,欢迎大家都来参加!

    网址:http://59.77.139.92/index.jsp

    A题:来源 POJ 2773

    题意:给两个数m和k,问第k 个和m 互素的数是多少(从1到无穷大)。

    思路:

      二分 + 容斥

      先求出m 的素因子p[],数x 和m 互素就意味着x 不存在p 数组中的任意一个素因子,现在要 求n 下面不存在p[]素因子的数的数量可以转化为,n-存在p[]中任意一个素因子的数的个数(经典题型,用容斥可以求),现在二分(k,INF)可以求出答案。

     1 #include<stdio.h>
     2 #define N 1000010
     3 #define LL long long
     4 const LL INF = 0x7fffffffffffffff;
     5 bool pri[N];
     6 int prim[N], po=0;
     7 void Init()
     8 {
     9   for(int i=2;i<N;i++)
    10   {
    11     if(!pri[i]) prim[po++]=i;
    12     for(int j=0;j<po&&(LL)i*prim[j]<N;j++)
    13     {
    14       pri[i*prim[j]]=1;
    15       if(i%prim[j]==0) break;
    16     }
    17   }
    18 }
    19 
    20 int data[30], co;
    21 
    22 void fun(int x)
    23 {
    24   int i=0;
    25   co=0;
    26   while(i<po && (LL)prim[i]*prim[i]<=x)
    27   {
    28     bool c=0;
    29     while(x%prim[i]==0)
    30     {
    31       c=1;
    32       x/=prim[i];
    33     }
    34     if(c) data[co++]=prim[i];
    35     i++;
    36   }
    37   if(x!=1) data[co++]=x;
    38 }
    39 
    40 void dfs(int limit, int j, LL y, LL now, LL &all)
    41 {
    42   if(limit==0)
    43   {
    44     all += y/now;
    45     return ;
    46   }
    47   for(int i=j; i<co; i++)
    48   {
    49     dfs(limit-1, i+1, y, now*data[i], all);
    50   }
    51 }
    52 LL solve(LL x)
    53 {
    54   LL sum=x, flag=-1;
    55   for(int i=1; i<=co; i++)
    56   {
    57     LL all=0;
    58     dfs(i, 0, x, 1, all);
    59     sum+=flag*all;
    60     flag *= -1;
    61   }
    62   return sum;
    63 }
    64 
    65 LL er(LL l, LL r, LL x)
    66 {
    67   while(l<r)
    68   {
    69     LL mid = (l+r)/2;
    70     if(solve(mid)>=x) r=mid;
    71     else l=mid+1;
    72   }
    73   return l;
    74 }
    75 
    76 int main()
    77 {
    78   Init();
    79   int x,y;
    80   while(~scanf("%d%d",&x, &y))
    81   {
    82     fun(x);
    83     printf("%lld
    ", er(y, INF, y));
    84   }
    85   return 0;
    86 }
    AC代码

    B题:来源 HDU 1730

    题意:

    思路:

      博弈

      很容易产生的错误判断:如果两个子相邻,那么这个的胜者是后手,如果不相邻,胜者是先手,那么判断先手胜利的行数,最后如果是奇数则先手胜,偶数则后手胜(我因此WA了两次...)。举个错误样例:,如果按上面思路,两行都是先手胜,那么应该是后手赢,但先手其实可以将第一行的红点移动一格,这样先手就赢了。

      事实上,这里应该是nim博弈的模型,首先,我们可以判断出一点,双方的棋子只会不断接近(如果一人后退一步,另一人可以跟进一步,保持局面不变)。接着,既然两者只能接近,那么就可以看作是n 堆,每一堆x个,每个玩家每轮可以拿走一个、两个、...直至拿完。接下来就不解释了。

     1 #include<stdio.h>
     2 int max(int a, int b) { return a>b?a:b; }
     3 int main()
     4 {
     5   int n, m, x, y;
     6   while(~scanf("%d%d",&n, &m))
     7   {
     8     int ans = 0;
     9     for(int i=0; i<n; i++)
    10     {
    11       scanf("%d%d",&x, &y);
    12       if(x+1==y || x==y+1);
    13       else ans ^= ( max(x, y) - (x+y-max(x, y)) - 1);
    14     }
    15     if(ans) printf("I WIN!
    ");
    16     else printf("BAD LUCK!
    ");
    17   }
    18   return 0;
    19 }
    AC代码

    C题:来源 POJ 3671

    题意:

    思路:

      用两个数组a[]、b[],a[i]表示i前面2的个数,b[i]表示i后面1的个数(遍历两遍可以求出a、b数组),如果以i 为中心(1、2转折点),要修改的数个数为a[i-1]+b[i+1],遍历一遍求出最小值即可。

     1 #include<stdio.h>
     2 #define N 30010
     3 int a[N], b[N], c[N];
     4 int main()
     5 {
     6   int n;
     7   while(~scanf("%d",&n))
     8   {
     9     a[0]=0;
    10     for(int i=1; i<=n; i++)
    11     {
    12       scanf("%d", &c[i]);
    13       if(c[i]==1) a[i]=a[i-1];
    14       else a[i]=a[i-1]+1;
    15     }
    16     b[n+1]=0;
    17     for(int i=n; i>0 ;i--)
    18     {
    19       if(c[i]==1) b[i]=b[i+1]+1;
    20       else b[i]=b[i+1];
    21     }
    22     int mint = N;
    23     for(int i=1; i<=n; i++)
    24     {
    25       if(a[i-1]+b[i+1]<mint) mint = a[i-1]+b[i+1];
    26     }
    27     printf("%d
    ", mint);
    28   }
    29   return 0;
    30 }
    AC代码

    D题:来源 POJ 3663

    题意:

    思路:

      排序 + 二分

       对数组排序后,遍历一遍,s-a[i]就是分界点,二分出小于等于他的第一个数,比他小的都满足条件。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 int a[20005];
     7 int er(int l, int r, int x)
     8 {
     9   while(l<r)
    10   {
    11     int mid = (l+r)/2;
    12     if(a[mid]<=x) l=mid+1;
    13     else r=mid;
    14   }
    15   return l;
    16 }
    17 
    18 int main()
    19 {
    20   int n, m;
    21   while(~scanf("%d%d",&n,&m))
    22   {
    23     for(int i=0; i<n; i++)
    24       scanf("%d", &a[i]);
    25     sort(a, a+n);
    26     int ans = 0;
    27     for(int i=n-1; i>0; i--)
    28     {
    29       int x = m-a[i];
    30       int num = er(0, i, x) - 0;
    31       ans += num;
    32     }
    33     printf("%d
    ", ans);
    34   }
    35   return 0;
    36 }
    AC代码

    E题:来源 POJ 1028

    题意:

    思路:

      随手写个栈模拟一下就好了。

     1 #include<stack>
     2 #include<string>
     3 #include<iostream>
     4 using namespace std;
     5 
     6 string st[200];
     7 int top=0;
     8 int mt=0;
     9 
    10 void push(string s)
    11 {
    12   st[++top]=s; mt=top;
    13 }
    14 
    15 void pop()
    16 {
    17   if(top==0) cout<<"Ignored"<<endl;
    18   else cout<<st[--top]<<endl;
    19 }
    20 
    21 int main()
    22 {
    23   st[top]="http://www.acm.org/";
    24   string s;
    25   while(cin>>s)
    26   {
    27     if(s[0]=='Q') break;
    28     if(s[0]=='V')
    29     {
    30       cin>>s; cout<<s<<endl;
    31       push(s);
    32     }
    33     else if(s[0]=='B') pop();
    34     else if(top==mt) cout<<"Ignored"<<endl;
    35     else cout<<st[++top]<<endl;
    36   }
    37   return 0;
    38 }
    AC代码

      

  • 相关阅读:
    Flutter开发指南之理论篇:Dart语法05(单线程模型,事件循环模型,Isolate)
    跨平台将终结
    一万字详解 Redis Cluster Gossip 协议
    Java实现简单的计算器
    CSDN开发者周刊第 22期:谷歌 DeepMind 第四代:不学规则就可以玩游戏;图灵奖得主 Edmund Clarke 因感染“新冠”逝世;
    理解Python闭包,这应该是最好的例子
    sscanf函数用法详解
    web项目中配置多个数据源
    web项目中配置多个数据源
    动态表格之查看、删除、编辑
  • 原文地址:https://www.cnblogs.com/hchlqlz-oj-mrj/p/6188252.html
Copyright © 2011-2022 走看看