简单算法题

来源:互联网 发布:squareframe美图软件 编辑:程序博客网 时间:2024/05/29 03:00

题目一:设原始数组为a[],初始值均为0,我们对数列a[]进行两种操作:

       (1)对某些数加1     (2)对所有的数乘2

       问至少经过多少次操作达到给定的序列。

 

分析:先对给定的数组a[]中的奇数减1,然后对所有的数除以2,然后反复进行此操作,直到所有的数为0.



题目二: http://acm.hdu.edu.cn/showproblem.php?pid=2037

 

分析:先按节目的结束时间排序,越早结束的节目当然要先看,按照这样的方法处理。



题目三:http://acm.hust.edu.cn/problem.php?id=1618

 

题意:把1~n*n之间的数填入n*n的矩阵,使得所有两两相邻元素和的最大值最小,求这个最小值。例如n = 2时

1 4

3 2

这种方式形成的最小值为6,其余的填法形成的都比这个值大。

 

分析:这个最小值为:n^2 + n/2 + 1,证明无。



题目四:http://codeforces.com/contest/346/problem/C


题意:给两个数字a和b,a>=b,再给一个数组x[],现在我们要把a变成b,只能进行两种操作:


      (1)把a自减1       (2)把a减去a%x[i]


     现在求最小的步数把a变为b。


分析:本题是很明显的贪心算法。当然在开始之前我们首先要对数组x[]去重,当然这个用sort排一下序,然后用STL的unique,然后就是每次找a%x[i]的最大值,然后还要保证每次a减了之后要大于等于b。

#include <iostream>#include <string.h>#include <algorithm>#include <stdio.h>using namespace std;const int N = 100005;int x[N];int main(){    int n,a,b;    while(scanf("%d",&n)!=EOF)    {        for(int i=0; i<n; i++)            scanf("%d",&x[i]);        scanf("%d%d",&a,&b);        sort(x,x+n);        n = unique(x,x+n)-x;        int ans = 0;        while(a > b)        {            int maxval = 1;            for(int i=0; i<n; i++)            {                if(a - a%x[i] >= b)                    maxval = max(maxval,a%x[i]);            }            a -= maxval;            while(n && a-a%x[n-1] < b) n--;            ans++;        }        printf("%d\n",ans);    }    return 0;}



原创粉丝点击