2016.07.12 完成 9 道题

来源:互联网 发布:access数据库教程视频 编辑:程序博客网 时间:2024/06/08 05:34

UVA-575

如题目所描述的方法求出值就好了。

#include <iostream>#include <algorithm>#include <cstdio>#include <string>using namespace std;string s;int main () {    freopen("xx.in","r",stdin);    while (cin>>s){        if (s == "0") break;        int len = s.length();        int sum = 0;        for (int i = 0; i < len; i++){            sum +=(s[i]-'0') * ((1<<(len - i))-1);        }        printf("%d\n",sum);    }}

UVA-10110

题意:这个人第 i 次走过去时会把所有 i 的倍数的灯都按一次开关。求走 n 次后,第 n 盏灯是开还是关。
解题思路:对于一个数,它每存在一个因数它就会被按一次。对于完全平方数以外的数字的因数都是成对的,就是偶数次按,最后必然是关着的。所以只要判断是不是完全平方数就好了。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int n;int main () {    while (true) {        long long s,m=0;        scanf("%lld",&s);        if (s == 0) break;         long long t = sqrt(s);        if (t * t == s)  printf("yes\n");         else printf("no\n");    }}

UVA-550

题意:给定m,k,n。其中 m 为 m进制,n为一个固定乘数, k 为m进制下某个数字的末尾。要求这个数字最小为几位。
解题思路: 假设这个m进制数字 为 xxxxxxxk
我们可以做出模拟 now = k * n ,t = now % m ,则t是xxxxxxxk * n 结果的最后一位,也就是xxxxxxxk 的倒二位。即xxxxxxtk 。同时还可能有一个进位 z。通过 (t * n + z)% m可以求到倒三位。依次推下去,统计求来几位,知道某一位与k 相同。此时的位数就是最小位数。

#include <iostream>#include <algorithm>#include <cstdio>#include <string>using namespace std;int m,k,n,la;int main () {    freopen("xx.in","r",stdin);    while (scanf("%d%d%d",&m,&k,&n) != EOF){        la=0;        int now=k,x=0;        while (now*n + x != k) {            x = now*n + x;            now = x % m;            x = x / m;            la++;        }        la++;        printf("%d\n",la);    }}

UVA-568

题意:求 n! 中最后一位非零数字是多少。
解题思路:首先,因为零成任何数都是零,所以当最后一位出现0时就可以去掉了。然后,我们是不是只要保留最后一位能?不是这样的,因为最后一位可能乘上某个数就变成0了,就要知道它前面的是多少才能继续计算,如 32 × 5 = 160,末位是6,进了 1。保留6位就能解决了。

#include <iostream>#include <algorithm>#include <cstdio>#include <string>using namespace std;int n;int main () {    freopen("xx.in","r",stdin);    while (scanf("%d",&n) != EOF) {        long long ans=1;        for (int i = 1; i <= n; i++) {            ans = ans * i;            while (ans % 10 == 0) ans/=10;            ans = ans %  1000000;        }        while (ans % 10 == 0) ans/=10;        ans=ans%10;        printf("%5d -> %lld\n",n,ans);    }}

UVA-408

解题思路:判断2个数是不是互质。用辗转相除法就好了。

#include <iostream>#include <algorithm>#include <cstdio>#include <string>using namespace std;int gcd(int x, int y){    if (y == 0) return x;    else return gcd(y,x % y);}int main () {    int n,m;    freopen("xx.in","r",stdin);    while (scanf("%d%d",&n,&m) != EOF){        printf("%10d%10d    ",n,m);        if (gcd(n,m) == 1) printf("Good Choice\n");        else printf("Bad Choice\n");        printf("\n");    }}

UVA-350

题意:给Z,I,M,L,求经过多少次 newL = ( z*l + i ) mod m 之后 newL会出现重复。
解题思路:暴力模拟,要注意最开始的 L 不一定就在newL的变化之中。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;int z,m,l,i;int pd[300000];int main () {    int n=0;    freopen("xx.in","r",stdin);    while (true) {        scanf("%d%d%d%d",&z,&i,&m,&l);        memset(pd,0,sizeof (pd));        if (z == 0) break;        int now = z*l + i, cnt=1;        now = now %m;        pd[l] = 1;        while ( !pd[now] ) {            pd[now] = 1;            now = z*now +i;            now %=m;            cnt++;        }        if (now != l)  cnt --;        n++;        printf("Case %d: %d\n",n,cnt);    }}

UVA-10061

题意:给出 N,B。求 N!在 B 进制下末尾有多少个 0 和有多少位。
解题思路: 对于任意m进制和十进制 S之间的位数关系,假设十进制转成B进制后有k位,就会有这样一个关系:
B^(k-1) <= S <=B^k。如果S = N!,那么就是 B^(k-1) <= N!<=B^k。以m为底取log。就会有∑log B i (i= 1 to n) <= k。因为c++只有默认以e或10 为底数的log函数,需要套换底公式。
关于有多少个0的问题,我们知道在10下面我们是看所有质因数中 2 和 5 能配出多少对就有多少个0,在B进制下也能通过求质因数的方式来判断有多少个0。我们只要知道B有哪些质因数,求 1~N中能获得多少这些质因数,计算一下就好了。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int n,pi[300],lp,b,tot[300],z[300];bool pd[900];int main () {    freopen("xx.in","r",stdin);    while (scanf("%d%d",&n,&b)!=EOF){        memset(pd,true,sizeof(pd));        memset(pi,0,sizeof(pi));        memset(tot,0,sizeof(tot));        memset(z,0,sizeof(z));        lp=0;        for (int i = 2; i <= b; i++)            if (b % i == 0 &&  pd[i]){                pi[++lp] = i;                for (int j = 1; i*j <= b; j++)                    pd[i*j] =false;            }        double s=0.000000000000;        for (int i = 1; i <= n; i++)            s=s+log(i+0.0);        s= s / log(b+0.0) +1e-8;        int m = s;        if (m < s) m++;        for (int l = 1; l <= n; l++){            int k = l;            for (int i = 1; i <= lp; i++)                while (k % pi[i] == 0  && k){                    tot[i]++;                    k/=pi[i];                }        }        for (int i = 1; i <= lp; i++)            while (b &&  b % pi[i] == 0) {                z[i]++;                b/=pi[i];            }        int sum = 999999999;        for (int i = 1; i <= lp; i++)             sum = min(sum,tot[i]/z[i]);        printf("%d %d\n",sum,m);    }}

UVA-10392

题意:求n的因数分解。
解题思路:因为题目保证最多只有一个大于1000000 的质因数,听说可以暴力不断从2开始跑,遇到能整除的就整除,然后在从2开始跑。
我这里是复习了下线性筛法求素数。然后也是拿一个素数,能整除时就一直除一直输出,不行换下一个,知道素数表完了,如果 n != 1 再把n输出来。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;bool pd[1001000];int pi[80000],lp;int main () {    freopen("xx.in","r",stdin);    lp=0;    memset(pd,true,sizeof(pd));    for (int i = 2; i < 1000000; i++) {        if (pd[i]) pi[++lp] = i;        for (int j = 1; j <= lp  &&  i*pi[j] < 1000000; j++) {            pd[i*pi[j]] =false;            if (i % pi[j] == 0) break;        }    }    long long n;    while (true) {        scanf("%lld",&n);        if (n == -1) break;        for (int i = 1; i <= lp && pi[i] <= n; i++)            while (n % pi[i] == 0  &&  n) {                n/=pi[i];                printf("    %d\n",pi[i]);            }        if (n != 1) printf("    %lld\n",n);        printf("\n");    }}

UVA-10879

题意:把 n 写成 n = A * B = C * D 的形式,其中ABCD大于 1 。
解题思路: 其实不明白这题想干嘛。。。循环从2开始,遇到是n因数的就输出来。输完2个break循环就好了。

#include <iostream>#include <algorithm>#include <cstdio>#include <string>using namespace std;int t,n;int main () {    scanf("%d",&t);    for (int l = 1; l <= t; l++) {        scanf("%d",&n);        printf("Case #%d: %d ",l,n);        int z=0;        for (int i = 2; i < n; i++)            if (n % i == 0) {                printf("= %d * %d ",i,n/i);                z++;                if (z == 2) break;            }        printf("\n");    }}
0 0