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 }