[Contests]2016 ACM/ICPC Asia Regional Qingdao Online(1001/2/4/5/6)

来源:互联网 发布:人工智能 大学排名 编辑:程序博客网 时间:2024/05/01 19:02

1001 I Count Two Three

题意:

给你一个数n(1<=n<=1e9),让你求一个数re,re满足re=2a3b5c7d && re>=n

思路:

打表+二分

代码:

#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;/*打表+二分*/const int N = 500000+5;int tab[N];int n=0, num;__int64 my_pow(int x, int num){    __int64 sum=1;    while(num>0){        sum *= x;        num--;    }    return sum;}//打表void table(){    int i,j,k,w;    __int64 tmp=0;    for(i=0; i<=30; i++)    for(j=0; j<=19; j++)    for(k=0; k<=13; k++)    for(w=0; w<=11; w++){        tmp = my_pow(2,i) * my_pow(3,j);        if(tmp>1e9) break;        tmp *= my_pow(5,k);        if(tmp>1e9) break;        tmp *= my_pow(7,w);        if(tmp>1e9) break;        tab[n++] = tmp;    }    sort(tab,tab+n);}int main(){    int t;    table();//5174个    scanf("%d", &t);    while(t-->0){        scanf("%d", &num);        int x = lower_bound(tab,tab+n,num)-tab;        printf("%d\n", tab[x]);    }    return 0;}


1002 Cure

题意:

给你一个数n,让你求1/k^2(1<=k<=n)的和,但是没给n的具体范围,给了这个“The input file is at most 1M.”也不懂啥意思……

思路:

一开始直接记忆化搜索,然后理所当然的TLE了_(:зゝ∠)_

然后通过打表发现n过大时基本都是1.64493,也就是n>=1e6的时候,所以打表的范围有了,就是[1,1e6];

然后用字符串读入n,如果n的长度>=7,直接输出1.64493即可

代码:

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;const int N = 1e6+5;char arr[N];double f[N];//f[x] the sum before x;//打表void table(){    double ans=0.0;    for(int i=1; i<=1e6; i++){        ans += 1.0/i/i;        f[i] = ans;    }}int main(){    int n,len;    table();    while(~scanf("%s", arr)){        len = strlen(arr);        if(len >= 7){            printf("%.5f\n", f[1000000]);            continue;        }        n = 0;        for(int i=0; i<len; i++)            n = 10*n + (arr[i]-'0');        printf("%.5f\n", f[n]);    }    return 0;}


1004 Tea

题意:

这诗一样的题目描述我很无语,概括一下就是:
两个杯子和一个壶,你要往杯子里倒水,尽可能的倒水次数少;//倒一个杯子就算一次,而不是倒两个杯子才算一次!!!
倒进杯子里的水可见,但壶里剩余水量不知,但你会知道是否空了,且知道壶里水的初始量是[L,R]这个范围;
到最后呢,壶里剩余水<=1个单位,杯子间差<=1个单位

思路:

这种找规律的题就是猜呀猜,然后找特例_(:зゝ∠)_
① r<=1 不需要倒水
② 1<r<=2 倒一次就够
③ r-l<=2 倒两次,第一次填L/2+0.5,第二次填[L-L/2,R-1-L/2](以(6,8)(7,9)为例,满足)

④ 否则,依次倒水L/2, L/2+1, L/2+1-L/2+1, L/2 + (L/2+1-L/2+1) - (L/2+1) +1……如此下去就是 L/2, L/2+1, 2, 2……

可总结规律为(L/2 + L/2+1 + 2 + 2 + ……)(共n次)=(R-1); 即n = (R-L)/2+1;

按照找到的规律写代码即可

代码:

#include <iostream>#include <stdio.h>#include <string.h>/*这种找规律的题就是猜呀猜,然后找特例r<=1 不需要倒水1<r<=2 一次就够r-l<=2 第一次填L/2+0.5,第二题填[L-L/2,R-1-L/2](以(6,8)(7,9)为例,满足)否则,依次倒水L/2, L/2+1, L/2+1-L/2+1, L/2 + (L/2+1-L/2+1) - (L/2+1) +1……如此下去就是 L/2, L/2+1, 2, 2…… 可总结规律为(L/2 + L/2+1 + 2 + 2 + ……)(共n次)=(R-1);即n = (R-L)/2+1;*/using namespace std;__int64 judge(__int64 l, __int64 r){    if(r<=1) return 0;    if(r<=2) return 1;    if(r-l<=2) return 2;    l = max(l,1LL);    return (r-l)/2+1;}int main(){    __int64 l, r;    while(~scanf("%I64d%I64d", &l, &r)){        printf("%I64d\n", judge(l,r));    }    return 0;}


1005 Balanced Game

题意:

高中玩过的“rock-scissors-paper-Spock-lizard”游戏,就是“石头剪刀布”的加强版
一共十条关系,每个都制约俩且被俩制约
题目给出这种平衡游戏的形状数目,求能否平衡

思路:

当前形状会制约n/2个形状,且会被n/2个形状指向,所以n = n/2*2+1;
那么n必须是个>=3(首先保证成环)的偶数

代码:

#include <iostream>#include <stdio.h>#include <string.h>/*高中玩的“rock-scissors-paper-Spock-lizard”游戏,就是“石头剪刀布”的加强版一共十条关系,每个都制约俩且被俩制约题目给出这种平衡游戏的形状数目,求能否平衡当前形状会制约n/2个形状,且会被n/2个形状指向,所以n = n/2*2+1;n必须是个>=3(首先保证成环)的偶数*/using namespace std;int main(){    int t, n;    scanf("%d", &t);    while(t-->0){        scanf("%d", &n);        if(n%2 == 0){            printf("Bad\n");            continue;        }        printf("Balanced\n");    }    return 0;}


1006 The Best Path

题意:

n个湖,m条河,每个湖有一个value,每经过一次就异或这个当前湖的value,求经过所有河且只经过一次并使异或值最大的异或值;

如果不能经过所有河就输出“Impossible”

思路:

通过图(无向图或有向图)中所有边且每边仅通过一次的通路称为欧拉通路,相应的回路称为欧拉回路。具有欧拉回路的图称为欧拉图(Euler Graph),具有欧拉通路而无欧拉回路的图称为半欧拉图。

根据欧拉图和半欧拉图的定义,我们可以知道这就是我们要求的!

离散数学,判断是否是欧拉图/半欧拉图(奇度为2/0)

先判断是否是欧拉通路(奇度为2),异或所有deep/2%2为奇数的value;
再判断是否是欧拉回路(奇度为0),如果是就枚举起点异或之

代码:

#include <stdio.h>#include <string.h>#include <iostream>#include<vector>using namespace std;const int N = 1e5+5;int val[N];int deep[N];int main(){    int t, n, m;    int x, y;    scanf("%d", &t);    while(t-->0){        memset(deep,0,sizeof(deep));        scanf("%d%d", &n, &m);        for(int i=1; i<=n; i++)            scanf("%d", &val[i]);        while(m-->0){            scanf("%d%d", &x, &y);            deep[x]++;            deep[y]++;        }        int tmp=0;        for(int i=1; i<=n; i++)        if(deep[i]&1) tmp++;        if(tmp!=2 && tmp!=0){            printf("Impossible\n");            continue;        }        //欧拉通路        int ans = 0;        for(int i=1; i<=n; i++)        if(((deep[i]+1)/2)&1)            ans ^= val[i];        //欧拉回路-枚举起点        int re = 0;        if(tmp==0){            for(int i=1; i<=n; i++)                re = max(re,ans^val[i]);        }        else            re = ans;        printf("%d\n", re);    }}


1011 Barricade 是最短路+最小割问题,等看完“最小割”相关知识后再回头做,先搁着_(:зゝ∠)_

0 0
原创粉丝点击