• 7/25 CSU-ACM2018暑假集训比赛1


    题目链接

    [A - Tricky Sum ]
    In this problem you are to calculate the sum of all integers from 1 to n, but you should take all powers of two with minus in the sum.

    For example, for n = 4 the sum is equal to  - 1 - 2 + 3 - 4 =  - 4, because 1, 2 and 4 are 20, 21 and 22 respectively.

    Calculate the answer for t values of n.

    Input
    The first line of the input contains a single integer t (1 ≤ t ≤ 100) — the number of values of n to be processed.

    Each of next t lines contains a single integer n (1 ≤ n ≤ 109).

    Output
    Print the requested sum for each of t integers n given in the input.

    Examples
    Input
    2
    4
    1000000000
    Output
    -4
    499999998352516354
    Note
    The answer for the first sample is explained in the statement.

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 1e6 + 20;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int t,m;
    LL n;
    int a[maxn];
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            LL sum=0;
            cin>>n;
            sum = n*(n+1)/2; //先不管正负都加起来,即前n项和,有公式
            for(int i=0; pow(2,i)<=n; i++)
                sum-=(2*pow(2,i)); //减两次2的幂,那么一次抵消,一次真正减去
            cout<<sum<<endl;
        }
    }
    
    

    [B - Queries about less or equal elements ]
    You are given two arrays of integers a and b. For each element of the second array bj you should find the number of elements in array a that are less than or equal to the value bj.

    Input
    The first line contains two integers n, m (1 ≤ n, m ≤ 2·105) — the sizes of arrays a and b.

    The second line contains n integers — the elements of array a ( - 109 ≤ ai ≤ 109).

    The third line contains m integers — the elements of array b ( - 109 ≤ bj ≤ 109).

    Output
    Print m integers, separated by spaces: the j-th of which is equal to the number of such elements in array a that are less than or equal to the value bj.

    Examples
    Input
    5 4
    1 3 5 7 9
    6 4 2 8
    Output
    3 2 1 4
    Input
    5 5
    1 2 1 2 5
    3 1 4 1 5
    Output
    4 2 4 2 5
    【二分】:求在第一个数组a中小于第二个数组b中的数的个数、即a数组排序后中可以插入的位置。

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 1e6 + 20;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int t,m,n;
    int a[maxn];
    int b[maxn];
    int x[maxn];
    int main()
    {
       scanf("%d%d",&n,&m);
    
            int pos,k=0;
            ms(a,0);
            ms(b,0);
            for(int i=0;i<n;i++)
            {
                scanf("%d",&a[i]);
            }
            sort(a,a+n);
            for(int i=0;i<m;i++)
            {
                scanf("%d",&b[i]);
            }
            int flag=1;
            for(int i=0;i<m;i++)
            {
                pos = upper_bound(a,a+n,b[i])-a;
                if(flag) {cout<<pos;flag=0;}
                else cout<<' '<<pos;
            }
    
    }
    

    C - 极角
    You are given the set of vectors on the plane, each of them starting at the origin. Your task is to find a pair of vectors with the minimal non-oriented angle between them.

    Non-oriented angle is non-negative value, minimal between clockwise and counterclockwise direction angles. Non-oriented angle is always between 0 and π. For example, opposite directions vectors have angle equals to π.

    Input
    First line of the input contains a single integer n (2 ≤ n ≤ 100 000) — the number of vectors.

    The i-th of the following n lines contains two integers xi and yi (|x|, |y| ≤ 10 000, x2 + y2 > 0) — the coordinates of the i-th vector. Vectors are numbered from 1 to n in order of appearing in the input. It is guaranteed that no two vectors in the input share the same direction (but they still can have opposite directions).

    Output
    Print two integer numbers a and b (a ≠ b) — a pair of indices of vectors with the minimal non-oriented angle. You can print the numbers in any order. If there are many possible answers, print any.

    Examples
    Input
    4
    -1 0
    0 -1
    1 0
    1 1
    Output
    3 4
    Input
    6
    -1 0
    0 -1
    1 0
    1 1
    -4 -5
    -4 -6
    Output
    6 5
    【题意】:有n个点,每个点表示原点到该点的向量,让你求出两个向量最小的夹角,输出向量的序号
    【分析】:该题需要用到高精度计算角度的方法.用atan2(y,x)能够求出每个点与x轴正向的夹角,进行排序,
    在从小到大枚举角度,注意最后一个角度(最大角)和第一个角度(最小角)的角度差可能是负值,要加上2*PI

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef long double ld;
    
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 1e6 + 20;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int n;
    struct node
    {
        ld x,y,id; //需要记录位置又要排序,故设置id
    
    }a[maxn];
    bool cmp(node p1,node p2) //按照极角排序
    {
        return atan2(p1.y,p1.x) < atan2(p2.y,p2.x);
    }
    int main()
    {
        scanf("%d",&n);
        rep(i,0,n)
        {
            cin>>a[i].x>>a[i].y;
            a[i].id=i;
        }
        sort(a,a+n,cmp);
        ld ans=PI*100; //扩大100倍防止精度问题,不影响答案,答案是记录位置
        int x, y;
        a[n]=a[0];//因为是圆,首位相连
        for(int i=1;i<=n;i++)
        {
            ld t = atan2(a[i].y,a[i].x) - atan2(a[i-1].y,a[i-1].x);
            if(t<0) t += 2*PI; //负数则+360°
            if(ans>t) //求出最大角度
            {
                ans=t;
                x=a[i].id; //排序后相邻
                y=a[i-1].id;
            }
        }
        cout<<x+1<<' '<<y+1<<endl;
    }
    

    E - Mafia
    One day n friends gathered together to play "Mafia". During each round of the game some player must be the supervisor and other n - 1 people take part in the game. For each person we know in how many rounds he wants to be a player, not the supervisor: the i-th person wants to play ai rounds. What is the minimum number of rounds of the "Mafia" game they need to play to let each person play at least as many rounds as they want?

    Input
    The first line contains integer n (3 ≤ n ≤ 105). The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the i-th number in the list is the number of rounds the i-th person wants to play.

    Output
    In a single line print a single integer — the minimum number of game rounds the friends need to let the i-th person play at least ai rounds.

    Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

    Examples
    Input
    3
    3 2 2
    Output
    4
    Input
    4
    2 2 2 2
    Output
    3
    Note
    You don't need to know the rules of "Mafia" to solve this problem. If you're curious, it's a game Russia got from the Soviet times: http://en.wikipedia.org/wiki/Mafia_(party_game).
    【题意】:其实也就是有n个人在玩游戏,这个游戏有一个规则就是每局必须有一个主持,(n-1)名选手其中第i个人表示想玩a[i]局游戏且不当主持;让求出满足每人要求的最少的局数:

    #include<cstdio>
    #include<string>
    #include<cstdlib>
    #include<cmath>
    #include<iostream>
    #include<cstring>
    #include<set>
    #include<queue>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<cctype>
    #include<stack>
    #include<sstream>
    #include<list>
    #include<assert.h>
    #include<bitset>
    #include<numeric>
    #define debug() puts("++++")
    #define gcd(a,b) __gcd(a,b)
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define fi first
    #define se second
    #define pb push_back
    #define sqr(x) ((x)*(x))
    #define ms(a,b) memset(a,b,sizeof(a))
    #define sz size()
    #define be begin()
    #define pu push_up
    #define pd push_down
    #define cl clear()
    #define lowbit(x) -x&x
    #define all 1,n,1
    #define rep(i,x,n) for(int i=(x); i<(n); i++)
    #define in freopen("in.in","r",stdin)
    #define out freopen("out.out","w",stdout)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef pair<int,int> P;
    const int INF = 0x3f3f3f3f;
    const LL LNF = 1e18;
    const int maxn = 1e6 + 20;
    const int maxm = 1e6 + 10;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int dx[] = {-1,1,0,0,1,1,-1,-1};
    const int dy[] = {0,0,1,-1,1,-1,1,-1};
    int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    int n;
    LL a,sum,Max;
    //最大化平均值
    bool check(LL x) //二分局数
    {
    	//局数*(n-1)人>=总局数
        return x*(n-1)>=sum;
    }
    int main()
    {
    	while(~scanf("%d", &n))
        {
    		Max=sum=0;
    		rep(i,0,n)
    		{
    			scanf("%I64d", &a);
    			sum+=a;
    			Max=max(Max,a);
    		}
            LL l,r,mid,ans;
    		l=Max, r=sum;
    		//朋友需要的最小游戏轮数,让第i个玩家至少玩ai轮次
    		while(l<=r)
    		{
    			mid = (l+r)/2;
    			if(check(mid))	r = mid-1,ans=mid;//最小化,由于单调增,合法后越小越左靠
    			else l = mid+1;
    		}
    		printf("%I64d
    ",ans);
    	}
    	return 0;
    }
    
    /*
    其实也就是有n个人在玩游戏,
    这个游戏有一个规则就是每局必须有一个主持,(n-1)名选手
    其中第i个人表示想玩a[i]局游戏且不当主持;让求出满足每人要求的最少的局数:
    */
    
  • 相关阅读:
    WPF 策略模式
    老陈 WPF
    老陈 ASP.NET封装
    小石头 封装
    典型用户故事
    整数的四则运算
    对git的认识
    如何学习计算机
    团队编程二——web应用之人事管理系统
    团队编程——web应用之人事管理系统
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9364844.html
Copyright © 2020-2023  润新知