zoukankan      html  css  js  c++  java
  • 几道数学题目

    poj 1026 http://poj.org/problem?id=1026

    题意:给你(乱序)数字,数字表示下面输入的字符串变幻的位置。比如说事例给的

    10(n)

    4 5 3 7 2 8 1 6 10 9

    1(k) Hello Bob

    1 代表对字符串中每一个字符进行变幻的次数。

    变幻的方式就是

    1 2 3 4 5 6 7 8 9 10(十个数排完序后)

    H e l l o B o b

    4 5 3 7 2 8 1 6 10 9

    这样经过 1 次变幻后,H到第四个位置(也就是字符串下标为 3 的位置)e变幻到第 5 个位置,依次类推。当然,如果 k 不等于 1,例如 k = 4, H 的变幻路径为 4 -> 7 -> 1 -> 4

    e的变幻路径为 2 -> 5 -> 2 -> 5 -> 2依次类推

    思路:其实模拟就行了,但是要加一些优化,否则会超时的。从上面可以看出,因为答案只是让求出每个字符的最终位置,可以求出所给的n个数的每一个的循环次数,这样用k取余循环次数,可以减少很多不必要的操作

    注意题目输出字符串时要求必须是 n 的长度,样例给的那个输出后面没有多余的空格,真是坑死人了。还有就是每个block后还要再输出一个空行,但是用puts输出就会PE,用printf输出就AC了,上网查了一下区别,只是说puts只是用来输出字符串的,其他的也没查出什么区别

    View Code
     1 #include <iostream>
     2 #include <math.h>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <string.h>
     6 #define N 210
     7 #define _clr(a,val) (memset(a,val,sizeof(a)))
     8 
     9 using namespace std;
    10 
    11 int tkey[N],key[N];
    12 int tind[N];  //用来保存每个数的循环次数
    13 int tem[N],v[N];// v[i]标记是否已经被计算过,因为在一个循环内的数的循环数是相等的,tem[i]用来记录一个循环内的编号
    14 char str[N],sbr[N];
    15 int cnt;
    16 void get_next(int n)
    17 {
    18     int i,sum,j;
    19     int cnt;
    20     _clr(v,0);
    21     for(i = 0; i < n; i++)
    22     {
    23         if(!v[i])
    24         {
    25             for(j = 0; j < n; j++)
    26             tem[j] = 0;
    27             v[i] = 1;
    28             j = i;
    29             sum = 1;
    30             cnt = 0;
    31             while(tkey[i] != key[j])  // 求循环数
    32             {
    33                 sum++;
    34                 tem[cnt++] = j;
    35                 v[j] = 1;
    36                 j = key[j] - 1;
    37             }
    38             v[j] = 1;
    39             tem[cnt++] = j;
    40             for(j = 0; j < cnt; j++)
    41             tind[tem[j]] = sum;
    42         }
    43     }
    44 }
    45 void chang(int n,int k)
    46 {
    47     _clr(sbr,0);
    48     int i,j,len;
    49     int temp;
    50     len = strlen(str);
    51     if(len < n)
    52     for(i = len; i < n; i++)
    53     str[i] = ' ';
    54     str[i] = '\0';
    55     for(i = 0; i < n; i++)
    56     {
    57         if(k == 1) temp = 1;
    58         else temp = k % tind[i];
    59         j = i;
    60         while(temp > 0)
    61         {
    62             if(tkey[i] == key[j]) temp--;   //循环数为 1 时做的处理
    63             while(tkey[i] != key[j])   // 查找最终的位置
    64             {
    65                 temp --;
    66                 j = key[j] - 1;
    67                 if(!temp) break;
    68             }
    69         }
    70         sbr[j] = str[i];
    71     }
    72     cout<<sbr<<endl;
    73 }
    74 int main()
    75 {
    76     int n,i,k;
    77     //freopen("data.txt","r",stdin);
    78     while(scanf("%d",&n),n)
    79     {
    80         for(i = 0; i < n; i++)
    81         {
    82             scanf("%d",&key[i]);
    83             tkey[i] = key[i];
    84         }
    85         sort(tkey,tkey + n);
    86         get_next(n);
    87         while(scanf("%d",&k),k)
    88         {
    89             getchar();
    90             gets(str);
    91             chang(n,k);
    92         }
    93         //puts("\n");  // 用puts结果总是PE,用printf就AC了
    94         printf("\n");
    95     }
    96     return 0;
    97 }

    poj 3270 http://poj.org/problem?id=3270

    题意:给出一个含有n 个数的序列,n个数中任意两个可以调换位置,使得目标序列为递增序列,调换位置付出的代价是两个数的和,怎样才能使得总代价最小,输出最小代价值

    刘汝佳 黑书 248页有关于这道题目的详细解答

    View Code
     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <iostream>
     6 #define _clr(a,val) (memset(a,val,sizeof(a)))
     7 #define N 10005
     8 #define inf 100001
     9 
    10 using namespace std;
    11 
    12 int  cow[N],v[N],tcow[N];
    13 int ind[inf];
    14 int main()
    15 {
    16     int n,i,j,k;
    17     int sum,minn,ans;
    18     int tem;
    19     //freopen("data.txt","r",stdin);
    20     while(scanf("%d",&n) != EOF)
    21     {
    22         //minn = inf;
    23         /*for(i = 0; i < n; i++)
    24         {
    25             v[i] = 0;
    26             ind[i] = 0;
    27         }*/
    28         for(i = 0; i < n; i++)
    29         {
    30             scanf("%d",&cow[i]);
    31             //if(cow[i] < minn) minn = cow[i];
    32             tcow[i] = cow[i];
    33             v[i] = ind[i] = 0;
    34         }
    35         sort(tcow, tcow + n);
    36         minn = tcow[0];
    37         for(i = 0; i < n; i++)
    38         {
    39             ind[tcow[i]] = i;
    40         }
    41         ans = 0;
    42         for(i = 0; i < n; i++)
    43         {
    44             if(!v[i])
    45             {
    46                 sum = 0;
    47                 tem = tcow[i];
    48                 j = i, k = 1;
    49                 v[j] = 1;
    50                 while(tcow[i] != cow[j])
    51                 {
    52                     sum += cow[j];
    53                     j = ind[cow[j]];
    54                     v[j] = 1;
    55                     k++;
    56                 }
    57                 if(k > 1)
    58                 {
    59                     ans += min(sum + (k - 1) * tem,sum + (k - 1) * minn + 2 * (tem + minn));
    60                 }
    61             }
    62         }
    63         printf("%d\n",ans);
    64     }
    65     return 0;
    66 }

    poj 2409 http://poj.org/problem?id=2409

    题意:给你 c 种颜色,s 个弹珠,问可以串出几种不同的手镯。

    如果做了poj 的 1286,再来做这道题目,就会觉得很简单了,因为只需改一下输入和计算时用的参数就可以了。 这两道题目是polya定理,置换群的应用中最裸的题目,关键就是如何找每个置换群的循环节数,我也是看的别人的解题报告,知道的如何找循环节数。给出两个参考链接,结合这看,应该是可以能够理解,http://www.cnblogs.com/yongze103/archive/2010/10/05/1842936.html   http://blog.sina.com.cn/s/blog_64d591e80100h8be.html。不过如果想知道那个公式怎么来的,有兴趣的可以去看 组合数学 第四版,或是  符文杰:《Pólya原理及其应用》

    View Code
     1 #include <iostream>
     2 #include <string.h>
     3 #include <math.h>
     4 #include <stdio.h>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 int gcd(int a,int b)
    10 {
    11     if(!b) return a;
    12     else return gcd(b,a % b);
    13 }
    14 int main()
    15 {
    16     int n,i,m;
    17     long long sum;
    18     //freopen("data.txt","r",stdin);
    19     while(cin>>m>>n,n + m)
    20     {
    21         sum = 0;
    22         if(!n)
    23         {
    24             cout<<"0\n";continue;
    25         }
    26         for(i = 1; i <= n; i++)
    27         {
    28             sum +=  (pow(1.0 * m,gcd(n,i)));
    29         }
    30         if(n % 2 == 0)
    31         {
    32             sum +=  ((pow(1.0 * m, n / 2 ) * (n / 2)));
    33             sum +=   ((pow(1.0 * m, (n + 2) / 2) * (n / 2)));
    34         }
    35         else sum +=  ((pow(1.0 * m, (n + 2) / 2) * n));
    36         sum = sum / (2 * n);
    37         printf("%lld\n",sum);
    38     }
    39     return 0;
    40 }

    poj 1286  http://poj.org/problem?id=1286

    View Code
     1 #include <iostream>
     2 #include <string.h>
     3 #include <math.h>
     4 #include <stdio.h>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 int gcd(int a,int b)
    10 {
    11     if(!b) return a;
    12     else return gcd(b,a % b);
    13 }
    14 int main()
    15 {
    16     int n,i;
    17     long long sum;
    18     //freopen("data.txt","r",stdin);
    19     while(cin>>n,n != -1)
    20     {
    21         sum = 0;
    22         if(!n)
    23         {
    24             cout<<"0\n";continue;
    25         }
    26         for(i = 1; i <= n; i++)
    27         {
    28             sum +=  (pow(3.0,gcd(n,i)));
    29         }
    30         if(n % 2 == 0)
    31         {
    32             sum +=  ((pow(3.0, n / 2 ) * (n / 2)));
    33             sum +=   ((pow(3.0, (n + 2) / 2) * (n / 2)));
    34         }
    35         else sum +=  ((pow(3.0, (n + 2) / 2) * n));
    36         sum = sum / (2 * n);
    37         printf("%lld\n",sum);
    38     }
    39     return 0;
    40 }

     

  • 相关阅读:
    一道关于js声明变量,var和let的面试题
    自执行匿名函数: (function() { /* code */ })();
    2017-09-26 开通博客第一天。 希望以后能够坚持更新,记录自己的成长,努力汲取各位朋友的知识见解。
    mybatis中根据日期模糊查询
    <![CDATA[文本内容]]>
    mybatis中sql标签和include标签
    Redis 安装
    Redis 简介
    从尾到头打印链表
    替换空格
  • 原文地址:https://www.cnblogs.com/fxh19911107/p/2517609.html
Copyright © 2011-2022 走看看