还是做完题目就写总结吧,晚上一块写,太多太累了。。
比赛地址: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=25950#overview
A:大水,小范围内求直角三角形个数
int main() { int n ; while(scanf("%d",&n)!=EOF) { int ans ; ans = 0; for(int i = 1 ; i <= n ; i ++ ) { for(int j = i + 1 ; j <= n ; j ++ ) { int tc = i * i + j * j ; int c = (int)sqrt((double)(tc)); if(c > n ) continue; if(c * c == tc ) { // printf("%d %d %d %d %d " ,i,j,c,c * c , tc); ans ++ ; } } } printf("%d ",ans); } return 0; }
B:两个日期之间的天数。一点点讨论吧。
int md[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; bool isleap(int year) { if( (year %4 == 0 && year % 100 != 0) || (year % 400 == 0 ) ) return true; else return false ; } int getyearday(int year) { if(isleap(year)) return 366; else return 365; } int getmonthday(int year , int month ) { if(month == 2 ) { if(isleap(year)) return 29; else return 28; } else return md[month]; } int main() { int year1 , month1 , day1; int year2 , month2 , day2; while(scanf("%d:%d:%d",&year1,&month1,&day1)!=EOF) { scanf("%d:%d:%d",&year2,&month2,&day2); if( (year2 < year1) || (month1 > month2 && year1 == year2 ) || (year1 == year2 && month1 == month2 && day2 < day1)) { swap(year1,year2); swap(month1,month2); swap(day1,day2); } int ans = 0 ; if(year1 == year2) { if( month1 == month2 ) { ans += (day2 - day1); } else { ans += (getmonthday(year1,month1) - day1); day1 = 1; month1 ++ ; if(month1 == 13) { month1 = 1 ; year1 ++ ; } while(month1 < month2 ) { ans += getmonthday(year1 , month1 ) ; month1 ++ ; } ans += day2; } } else { ans += day2 ; month2 -- ; while(month2 >= 1) { ans += getmonthday(year2,month2); month2 -- ; } year2 -- ; ans += (getmonthday(year1, month1) - day1); month1 ++ ; if(month1 == 13) { month1 = 1; year1 ++ ; } else { while(month1 <= 12) { ans += getmonthday(year1, month1); month1 ++ ; } year1 ++ ; } while(year1 <= year2) { ans += getyearday(year1); year1 ++ ; } } printf("%d ",ans); } return 0; }
C:0 到 n-1 的全排列,求出排列的一个三元组n(a,b,c),满足(ai + bi ) == ci (mod n ) ,两个等号表示同余吧
直接构造:n为偶数的时候无解,n为奇数的时候构造a为(0,1,2,....n-1),b为(n-1,0,1,2,....n-2)
int main() { int n ; while(scanf("%d",&n)!=EOF) { if(n % 2 == 1 ) { for(int i = 0 ; i < n - 1 ; i ++ ) printf("%d ", i ); printf("%d ", n - 1 ); printf("%d",n - 1);for(int i = 0 ; i < n - 1; i++ ) printf(" %d",i);printf(" "); int c ; printf("%d",n - 1); for(int i = 1; i < n; i ++ ) printf(" %d",(i + i - 1 ) % n );printf(" "); } else { printf("-1 "); } } return 0; }
D:骰子从上往下排列,相邻两个面不相同,问可不可以唯一确定每个骰子。只要确定想接触的面就可以了,要唯一的话必须使得点数与上一个的顶面点数相同。
int main() { int n ; int s; int tmp ; int a[105],b[105]; bool vis[10]; while(scanf("%d",&n)!=EOF) { scanf("%d",&s); tmp = s; scanf("%d%d",&a[1],&b[1]); for(int i = 2 ; i <= n ; i ++ ) scanf("%d%d",&a[i],&b[i]); bool flag; flag = true; tmp = s; for(int i =2 ; i <= n ; i++ ) { tmp = 7 - tmp ; memset(vis,0,sizeof(vis)); vis[a[i]] = 1; vis[7 - a[i]] = 1; vis[b[i]] = 1; vis[7 - b[i]] = 1; if(!vis[tmp]) { tmp = 7 - tmp ; } else { flag =false; break; } } if(!flag ) { printf("NO "); } else printf("YES "); } return 0; }
E:记得这题好像以前做过,但是没做出来。。
题意:给定k-bonacci 数定义如下,
- F(k, n) = 0, for integer n, 1 ≤ n < k;
- F(k, k) = 1;
- F(k, n) = F(k, n - 1) + F(k, n - 2) + ... + F(k, n - k), for integer n, n > k
然后给定s,k,求m个 k-bonacci数 使得和为s , 并且m至少为2
输入任意一种解即可。
分析:研究了一下这个数列,发现如果k很大的话就是:从k开始,1,1,2,4,8,16.....
然后就想如果k足够大,只要大于30 (保证这个即可(1<<k) >=s ),那么s一定可以用二进制表示出来,并且二进制是k-bonacci数,
如果不满足的话,那s肯定可以用k-bonacci数构造出来,直接从最大的开始找就行了(为什么啊,这里我是猜的。。。)。而且这个k-bonacci数列不会很长,最多60项,(31项不够,wa了,可以直接算到某一项比s大即可)。
还有为了保证至少两个数,可以直接往答案中插入一个0.
追加总结:其实想复杂了。直接把前面一部分项求出来,然后,直接从大到小减就行了。嗯,可以写的很简单很简单。。。。
#define maxn 500 vector<int> a; int f[maxn]; int s,k; int main() { while(scanf("%d%d",&s,&k)!=EOF) { if(k >= 30 || ( (k < 30) && ((1 << k ) > s ) ) ) { int tmp ; tmp = 1 ; a.clear(); a.push_back(0); while(s) { if(s & 1 ) { a.push_back(tmp); } tmp = tmp << 1; s >>= 1 ; } int sz = a.size(); printf("%d ",sz); for(int i = 0 ; i< sz - 1 ; i ++ ) { printf("%d ",a[i]); } printf("%d ",a[sz-1]); } else { a.clear(); a.push_back(0); for(int i = 0 ; i < k ; i ++ ) f[i] = 0; f[k] = 1; int i = k + 1 ; while(1 ) { f[i] = 0 ; for(int j = 1 ; j <= k ; j ++ ) { f[i] = f[i] + f[i - j]; } if(f[i] > s ) break; i ++ ; } int num = i ; /* printf("k_bonicai: "); for(int i = 0 ; i < 31 ; i ++ ) { printf("%d ",f[i]); } printf(" "); */ i = num; while(s > 0 && i >= k ) { if(f[i] <= s ) { s -= f[i]; a.push_back(f[i]); // printf("f[i] = %d ",f[i]); } i -- ; } int sz = a.size(); printf("%d ",sz); for(int i = 0 ; i< sz ; i++ ) { printf("%d",a[i]); if(i != sz - 1 ) printf(" "); } printf(" "); } } return 0; }