2018/8/23第三周

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

这个题思路很简单  就是求他的因数的个数  ,然后判断是奇数还是偶数,奇数次就是(1),否则就是(0),可以从一开始遍历   ,然后代码敲一半发现 了个神奇的东西

int yueshu(int x)
{
    int ans = 1;
    for(int i = 2; i < sqrt(x+1); i++)
    {
        if(x%i == 0)
        {
            ans += i;
        }
        else 
        {
            ans += (i+x/i);
        }
    }
    return ans;
}

你们有没有发现,就是如果他除以某个数如果不等与某个数 也就是(i ! = x / i)  ,那么他肯定会加入两个因数 ,所以,这下问题就简单了 ,只要证明他是不是完全平方数就好了,因为这样才会加入单独的一个解,然后发现咦,好像证明也要遍历,仔细一想可以用库函数呀sqrt呀 ,然后证明他的值是不是整数就好了,所以然后整个code,不到一分钟就敲出来了,如下:

int n;

while(cin >> n)
{
	if(sqrt(n) - (int)sqrt(n) == 0)
	{
		cout << "1" << endl;
	}
	else cout << "0" << endl;
}

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


题目第一眼看过去,入门难度的吧,然后越做越不对劲,题目什么都没给你,数据范围,整数还是浮点数 等等,所以一不小心就入坑了,
第一次code  和你们想的一样,直接用int存,然后判断相减是否为零 错了
第二次code,用double存,再次判断相减是否为零,错了
第三次code,用double存,相减再判断精确度就是相减是否小于10e-5,WA,
怀疑人生中
然后一想数据可能很坑,然后走向了用字符串存的道路,把小数点后的零删掉作比较,忘记了考虑小数点前是否有零,错了
然后继续字符串存,一个个乖乖的去调试,终于过了,就是先找有没有小数点,然后把小数点后面的零都删掉,因为他们零可能不一样多,比如30.0和30.00,还有30.000000000000000000000000000000000001和30.0000000000000000000000000000000000010;然后还有30和30.0,考虑了这些情况然后用个字符串比较函数就可以过了。代码如下:

void zhen(char *a)
{
	int len = strlen(a);
	int dian = -1;
	for(int i = 0; i < len; i++)
	{
		if(a[i] == '.')
		{
			dian = i;
		}
	}
	if(dian != 1)
	for(int i = len - 1; i >= 0; i--)
	{
		if(a[i] == '0')
		{
			a[i] == '\0';
		}
		else break;
		len--;
	}
	if(a[len-1] == '.') a[len-1] = '\0';
}

while(~scanf(%s%s), &n, &m);
{
	zhen(n), zhen(m);
	if(!strcmp(n,m))
	{
		cout << "YES" << endl;
	}
	else cout << "NO" << endl;
}

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

说明: 需要求在连续的1......n的序列里面找一个连续的子序列使得这个子序列的和等于m,可以看出这是一个等差数列的求和,公差都是1,每一个子序列的首项不一样。题目要求的是首项和尾项,假设首项是x,尾项是y那么求和公式就是(x+y) * (y-x+1) / 2 == sum;所以也就是 2*m == (x + y) * (y - x + 1); 但是注意到m的范围是m <= 1000000000,直接去枚举x或者是y是要GG(超时)所以可以考虑求(x+y),也就是找2*m的因子,求因子的话是可以开平方了再遍历的,所以时间复杂度就可以降下来了。当数据范围较大的时候,一定要考虑算法的时间复杂度,此时的m可以为1000000000,这个时候即使是O(n)的算法都是不可取的。然后等差数列求和还有一个公公式,假设首项为a, 长度为d,sum = a*d + d*(d-1)/2. 等价于 sum  = d*(a+(d-1)/2);和前面类似了。

/*第一种*/
	m = 2 * m;
	for(int i = sqrt(m); i >= 1; i--)
	{
	    if(m %i == 0)
		{
			int s = m/i, t = i;
			if((s-t+1)%2 == 0) //s和t同时为偶数的时候,求出来的就是小数了。
			{
				printf("[%d,%d]\n", (s-t+1)/2, (t+s-1)/2);
			}
		}
	}


/*第二种*/
   for(int i = sqrt(2 * m); i >= 1; i--)
    {
            int a = (m - ( ( i - 1 ) * i ) / 2) / i;
            if(m == a * i + ( i * ( i - 1 ) ) / 2)
            cout << '['<<a<<','<<a+i-1<<']' << endl;
    }

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

一开始我以为是一道贪心的模拟题,于是我就做了。结果错了想想对于每一个充电站其实只有两种可能的,那就是充电和不充电。选取最优的就好了,所以可能是DP。对于DP而言最难的地方我觉得就是状态转移方程了。对于这个题目而言,有几种想法,相同距离完成时间,相同时间完成距离。我采用的是第DP[i] 保存第i个充电站的最短的时间, 所以每次去想办法更新时间就好。到第i个充电站的时候,是从前面的充电过来的。所以遍历前面的所有充电站,因为对于到达前面每一个充电站的最优我们已经是找到了的.状态转移方程就是 dp[i]=min(Min,dp[j]+time);

/*
   p[] 保存每一个充电站的位置,从p[1]~p[N], C是充电后可以跑的距离,VT1乌龟有点的速度,VT2就是没有电的速度,L为总长度,VR是兔子的速度,dp[i]到达第i个充电站所要的最短时间
*/
       p[N + 1] = L;  //假定终点有一个充电站
        dp[0] = 0;  
        tr = L*1.0 / VR;  
        for (int i = 1; i <= N+1; i++)  
        {  
            double Min = 99999999;  
            for (int j = 0; j < i; j++)  
            {  
                int x = p[i] - p[j];  
                if (C >= x)  
                {  
                    time = x*1.0 / VT1;  
                }  
                else  
                {  
                    time = C*1.0 / VT1 + (x - C)*1.0 / VT2;  
                }  
                if (j )time += T;  
                if (Min> dp[j] + time)  
                {  
                    Min = dp[j] + time;  
                }  
            }  
            dp[i] = Min;  
        }  
        if (dp[N+1]>tr)  
            cout << "Good job,rabbit!" << endl;  
        else   
            cout << "What a pity rabbit!" << endl;  

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

 这个题目的背景就是介绍的斯诺克桌球,具体的规则可以百度,大致意思就是说,每次要先打进一个红球,才能去打其他的球。red(1 分),yellow(2 分), green(3 分), brown(4 分), blue(5 分), pink(6 分), black(7 分), 然后每次打进去一个不是红球的球就把这个球拿出来,红球不拿出来, 然后没有红球了就给对方玩。然后现在告诉你桌子上面一共有多少的球,然后告诉你两个玩家现在的得分,问题,如果玩家1全部打进去可以赢玩家2吗? 因为对于其他颜色的球,打进去后都是要拿出来的,一共有6个不同颜色的球,也就是有6个球。所以我们考虑两种情况,第一种是有红球,另一种是没有红球的。

       scanf("%d %d %d", &n, &a, &b);  
        if(n > 6)  
            a = a + (n - 6) * 8 + 27;  
        else  
            a = a + (15 - n) * n / 2;  
        if(a >= b)  
            printf("Yes\n");  
        else  
            printf("No\n");  

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

这是一个好玩的题目。 包分配对象一起坐过山车。这个好啊,什么时候班级活动也可以这样,但是题目说的是女生选男生,我希望我们班级聚会是男生选女生,毕竟班上女生多, 嘿嘿嘿嘿。对于这个题目告诉我们有A个女生B个男生,然后就是每一个女生可以接受和那些男生一起玩过山车。所以现在就是要幸福最大化,看看最多可以去多少对。对于测试样例,A1 = {1, 2, 3};A2 = {1,3}, A3 = {1};首先1号女生找到1号男生,发现1号男生没有对象,就坐在他旁边,然后2号女生看到1号男生旁边有人了,就去3号男生哪里。3号女生看到1号男生旁边是1号女生,就和1号商量,1号想了想,反正自己还有两种可能,就去找2号男生,发现2号男生有人了,就去找3号男生,发现没有人,就坐下来,所以最后就是A1 = B3   A2 = B2, A3 = B1.大家都开心了。实际上了这个题目是二分图里面的一个最大匹配问题

#include<bits/stdc++.h>
#define maxn 550

using namespace std;

bool flag[maxn][maxn]; ///flag[i][j] = 1说明i号女生可以和j 号男生坐在一起
int girl[maxn], user[maxn]; //girl[i] 表示 i号男生的旁边的女生,user[i]
// user[i], i号男生旁边有没有女生
int n, m, k;

int find(int x) //x是女生
{
    for(int i = 1; i <= m; i++)
    {
        if(flag[x][i] && !user[i]) //发现两个可以在一起,然后i号男生好像也没有人
        {
            user[i] = 1;  //标记一下
            if(!girl[i] || find(girl[i])) // 首先看i号男生有没有女生,没有的话就是自己了,有的话和她商量一下,看看她可不可以去找别人。
            {
                girl[i] = x;
                return 1;
            }
        }
    }
    return 0;
}

int main()
{
    //freopen("in.txt", "r", stdin);

    while(~scanf("%d %d %d", &k, &m, &n) && k)
    {
        memset(flag, false, sizeof(flag));
        memset(girl, 0, sizeof(girl));
        int x, y, sums = 0;
        for(int i = 0; i < k; i++)
        {
            scanf("%d %d", &x, &y);
            flag[x][y] = 1;
        }
        for(int i = 1; i <= n; i++)
        {
            memset(user, 0 ,sizeof(user));
            sums += find(i);
        }
        printf("%d\n", sums);
    }
    
    fclose(stdin);
    return 0;
}

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

这个题目有意思

说明:第一题,第二题,感谢蒋杨聘同学提供题解。第七题感谢段十怡老师指导,万分感谢。

猜你喜欢

转载自blog.csdn.net/qq_38736000/article/details/82194608
今日推荐