2013暑假集训第二天上午总结

还是做完题目就写总结吧,晚上一块写,太多太累了。。

比赛地址: 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 \n" ,i,j,c,c * c , tc);
                    ans ++ ;
                }
             }
        }

        printf("%d\n",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\n",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", n - 1 );
            printf("%d",n -  1);for(int i = 0 ; i < n - 1;  i++ ) printf(" %d",i);printf("\n");
            int c ;
            printf("%d",n - 1);
            for(int i = 1; i < n; i ++ ) printf(" %d",(i + i - 1 ) % n );printf("\n");
        }
        else
        {
            printf("-1\n");
        }
    }
    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\n");
        }
        else printf("YES\n");
    }
    return 0;
}

E:记得这题好像以前做过,但是没做出来。。

题意:给定k-bonacci 数定义如下,

  • F(k, n) = 0, for integer n1 ≤ n < k;
  • F(k, k) = 1;
  • F(k, n) = F(k, n - 1) + F(k, n - 2) + ... + F(k, n - k), for integer nn > 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\n",sz);
            for(int i = 0 ; i< sz - 1  ; i ++ ) {
                printf("%d ",a[i]);
            }
            printf("%d\n",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("\n");
*/
            i = num;
            while(s > 0  && i >= k ) {
                if(f[i] <= s ) {
                    s -= f[i];
                    a.push_back(f[i]);
                   // printf("f[i] = %d\n",f[i]);
                }
                i -- ;
            }
            int sz = a.size();
            printf("%d\n",sz);
            for(int i = 0 ; i< sz ; i++ ) {
                printf("%d",a[i]);
                if(i != sz - 1 ) printf(" ");
            }
            printf("\n");
        }
    }
    return 0;
}

posted on 2013-07-16 12:00  oshixiaoxiliu  阅读(271)  评论(2编辑  收藏  举报

导航