首页 > 代码库 > HDOJ2058解题报告

HDOJ2058解题报告

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=2058

题目概述:

  从1-n中找出所有和为m的子串。

大致思路:

  直接枚举答案的长度,很容易发现长度最长是sqrt(m),而长度只有可能是奇数或偶数,如果是奇数的话那么m%i一定要等于0,如果是偶数的话(m*2)%i一定要等于0。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <ctime>
 7 #include <map>
 8 #include <queue>
 9 #include <cstring>
10 #include <algorithm>
11 using namespace std;
12 
13 #define sacnf scanf
14 #define scnaf scanf
15 #define maxn 210
16 #define maxm 26
17 #define inf 1061109567
18 #define Eps 0.00001
19 const double PI=acos(-1.0);
20 #define mod 7
21 #define MAXNUM 10000
22 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
23 double Abs(double x) {return (x<0)?-x:x;}
24 typedef long long ll;
25 typedef unsigned int uint;
26 
27 int main()
28 {
29     //freopen("data.in","r",stdin);
30     //freopen("data.out","w",stdout);
31     //clock_t st=clock();
32     int n,m;
33     while(~scnaf("%d%d",&n,&m))
34     {
35         if(n==0&&m==0) break;
36         int i;ll temp;
37         for(i=1;;i++)
38         {
39             if(i&1) temp=(i+1)/2*i;
40             else temp=i/2*(i+1);
41             if(temp>m) break;
42         }
43         i--;
44         for(;i>0;i--)
45         {
46             int l=-1,r=n+1;
47             if(m%i==0)
48             {
49                 if(i&1)
50                 {
51                     l=(m/i)-(i/2);
52                     r=(m/i)+(i/2);
53                 }
54             }
55             else if((m*2)%i==0)
56             {
57                 if(i%2==0)
58                 {
59                     l=(m/i)-(i/2-1);
60                     r=(m/i)+(i/2);
61                 }
62             }
63             if(l>=1&&r<=n) printf("[%d,%d]\n",l,r);
64         }
65         printf("\n");
66     }
67     //clock_t ed=clock();
68     //printf("\n\nTime Used : %.5lf Ms.\n",(double)(ed-st)/CLOCKS_PER_SEC);
69     return 0;
70 }

 

HDOJ2058解题报告