2018/8/9第一周

第一题:http://acm.hdu.edu.cn/showproblem.php?pid=2018

这个题目是可以递归求解的,但是递归调用函数是需要时间的,并且递归会计算一些重复的东西,所以可以考虑记忆话递归。这样的话就不用重复的去计算了。然后对于每一个数字的结果都是差不多的。可以预处理用数组保存。

 a[1] = 1; ans[2] = 2; ans[3] = 3;
    for(int n = 4; n <= 55; n++)
        {
            ans[n] = ans[n-1] + ans[n-3];
        }

第二题:http://acm.hdu.edu.cn/showproblem.php?pid=2035

这个题目实际上是 快速幂 的简单应用,我尝试说一下大概意思.

求a^b.

如果b是偶数,那么a^b = a^(b/2)^2 = (a*a)^(b/2);

如果b是奇数,那么 a^b = a*a^(b-1),令c = b-1。 c就是偶数了,和上面的一样. 


int mod_pow(int x, int n) // 求x^n 
{
	int res = 1;
	while(n)
	{
		if(n&1) res = res*x%mod;  // 一般结果都比较大,所以有一个取余 
		x = x*x%mod;
		n >>= 1;
	}
	return res;
}

第三题:http://acm.hdu.edu.cn/showproblem.php?pid=2050

这是一个数学题。画图,想要得到最多的划分区间,就是让每一条线和尽可能多的线相交。提前说明,我画图蛇皮怪。

只有1对折线的时候,就是2, 2对7, 3对16。这是有道理的。如果不是折线(不是相交止于一个端点),是可以很快的发现可以划分的区间数是 3*n*n. 有了端点以后减少了n-1个端点,所以答案就是 3*n*n-(n-1) = 3*n*n-n+1;

第四题:http://acm.hdu.edu.cn/showproblem.php?pid=2089

这个题目好玩。如果不考虑时间的问题的话,是可以直接暴力的的去枚举区间里面的每一个数,然后取判断每一个数是不是含有62的。这样对于这道题目来说是可以的。但是这个题目,想一想,一个数里面有没有62和输入的区间有没有关系。显然是没有关系的。因此有没有62就是数的特性,就好比一个数是不是奇数一样,是数的一种特性,和需要求的区间是没有关系的。那么这种题目一般是用数位DP来解是比较好玩的。先给一般解法的代码。

/*
   time :795ms memory: 1200KB
*/
#include<stdio.h>

bool f(int x) //这个函数就是判断这个数是不是含有62
{
    while(x)
    {
        int n = x%10;
        if(n == 2 && x%100 == 62 || n == 4) return false;
        x = x/10;
    }
    return true;
}
int main()
{
    int n, m, sum = 0;
    while(scanf("%d%d", &n, &m) != EOF && n != 0 || m != 0)
    {
        for(int i = n; i <= m; i++)
        {
            if(f(i)) sum++;  
        }
        printf("%d\n", sum);
        sum = 0;
    }
    return 0;
}

下面是优化了的,相对于而言就好一点。

/*
   time:93ms memory:5312KB
*/
#include<iostream>
#include<string.h> 
#include<cstdlib>
using namespace std;
int ans[1000010];
int fun(int a)
{
    char str[10010]; // 这里是不需要开辟这么大的字符串的,想想最大的32 Int 2147483647,才10位,开辟12就可以了。// char str[12];
    itoa(a, str, 10);  //将a以10进制的形式放在str字符串里面.
    for(int i = 0; i < strlen(str); i++)
        if(str[i] == '4') return 0;
    for(int i = 0; i < strlen(str) - 1; i++)
        if(str[i] == '6' && str[i+1] == '2')  return 0;
    return 1;
}

int main()
{
    int m, n; ans[0] = 1;
    for(int i = 0; i <= 1000000; i++)
      ans[i] = ans[i-1] + fun(i);
    while(cin >> m >> n)
    {
        if(m == 0 && n == 0) break;
           cout << ans[n] - ans[m] + fun(m) << endl;
    }    
        return 0;
}

这个题目好玩,所以还有一种解法, 上面已经有了数位DP的想法了,但是还并不是的。

/*
  time: 0s memory:1676KB
*/
#include<iostream>  
#include<cstdio>  
#include<cstring>  
#include<string>  
using namespace std;  
typedef long long ll;  
int a[20];  
int dp[20][2];  
int dfs(int pos, int pre, int sta, bool limit)  
{  
    if(pos == -1) return 1;  
    if(!limit && dp[pos][sta] != -1) return dp[pos][sta];  
    int up = limit ? a[pos] : 9;  
    int tmp = 0;  
    for(int i = 0; i <= up; i++)  
    {  
        if(pre == 6 && i == 2)continue;  
        if(i == 4) continue;//都是保证枚举合法性  
        tmp += dfs(pos-1, i, i == 6, limit && i == a[pos]);  
    }  
    if(!limit) dp[pos][sta] = tmp;  
    return tmp;  
}  
int solve(int x)  
{  
    int pos = 0;  
    while(x)  
    {  
        a[pos++] = x%10;  
        x /= 10;  
    }  
    return dfs(pos-1, -1, 0, true);  
}  
int main()  
{  
    int le, ri;  
    while(~scanf("%d%d", &le, &ri) && le + ri)  
    {  
        memset(dp, -1, sizeof (dp));  
        printf("%d\n",solve(ri) - solve(le-1));  
    }  
    return 0;  
}  

第五题:http://acm.hdu.edu.cn/showproblem.php?pid=2007

虽然是一个很简答的题目。因为没有给定数据的范围,所以不太好做预处理。用平常的解法就好了。如果给定的数据的范围的话,先求出[1, n]的和,然后查询[a, b]就直接 sum[b]- sum[a] 就可以了。

第六题:http://acm.hdu.edu.cn/showproblem.php?pid=2013

这个题目和第五题类似,好一点就是给定了数据范围,就可以考虑进行预处理了。答案就是a[n]


	a[31] = { 0, 1 };
	for (i = 2; i < 31; i++) 
        {
	    a[i] = 2 * ( a[i - 1] + 1);
	}

 第七题:http://acm.hdu.edu.cn/showproblem.php?pid=2019

这就是一个比较简单的插排的思想,一般就是找一下位置,后移一下,插一下。找位置用二分查找,会好一点,后移和插入用链表好一点。但是二者不可兼得,链表不支持二分。对于这个题目。怎么玩都可以。建议使用二分去查找,找到了以后,保存一个位置,然后先输出前面的,然后输出待查找的值,然后输出后面的。也就是说不后移也不插进去,可以这样做的原因就是利用了评测机制。只要输出的是一样的,就可以了,但是如果是自己的做课程设计和项目的时候,还是要找到位置,后移,插入。

猜你喜欢

转载自blog.csdn.net/qq_38736000/article/details/81979294