zoukankan      html  css  js  c++  java
  • 牛客nowcoder NOIP普及组第三场

    qtmd AK了

    直接题解吧

    题目链接

    A-十七边形

    牛牛想在一个半径为r的圆中,找到一个内接的十七边形,使他的面积最大。输入半径r,输出最大的面积。 1 <= r <= 10000

    在10组数据中,存在5组数据,半径为1,10,100,1000,10000。 换句话说,对于50%的数据,r是10的次幂。

    输出保留6位小数

    Solution:肯定是正十七边形喽

    xjb证下:内接的十七边形一定把圆心角分为17份

    那么根据叉积算面积,(displaystyle S=frac {r^2} 2 sum_{i=1}^{17}sin( heta_i)),然后不会证了,反正十七个( heta)相等一定是坠吼的

    #include <bits/stdc++.h>
    using namespace std;
    
    int r;
    
    int main()
    {
    	scanf("%d", &r);
    	double fk = acos(-1) * 2 / 17.0;
    	double area = r * r * sin(fk);
    	area = area / 2.0 * 17;
    	printf("%f
    ", area);
    	return 0;
    }
    

    B-首都

    在平面上有n个整点(横纵坐标都是整数) 牛牛想找到一个整点,使得这个点,到所有点的距离之和最小。 两个点的距离定义为从一个点走到另一个点的最小步数。 其中每步可以走向相邻8个点(上,下,左,右,左上,左下,右上,右下,类似国际象棋中的王)走一步。 输出这个最小的距离之和,和这个点选择的方案数。(即有多少个点,可以达到这个最小的距离)

    对于100%的数据,1 <= n <= 100000,|x|, |y| <= 1000000000 对于40%的数据,1 <= n <= 100,|x|, |y| <= 100 对于以上每部分数据,都有50%的数据n是奇数。

    Sol:将坐标系顺时针旋转45度再放大一个(sqrt2),根据线性变换理论,((x,y) ightarrow(x+y,x-y))

    这样切比雪夫距离变味了曼哈顿距离,然后根据中位数定理求解

    需要分各种情况讨论

    N是奇数,根据中位数定理,只有一个点是最小值。但是,但是,这个点可能不合法。。。我们再逆变换变换回去,求(A=egin{pmatrix}1&1\1&-1end{pmatrix})的逆矩阵。行列式(detegin{vmatrix}1&1\1&-1end{vmatrix}=-2),伴随矩阵(A^*=egin{pmatrix}-1&1\1&1end{pmatrix}),逆矩阵为(egin{pmatrix}frac 1 2&-frac 1 2\-frac 1 2&-frac 1 2end{pmatrix}),显然我们需要两个数的奇偶性相同才行。不会用线性代数利器--矩阵推的同学可以画图观察,很显然的结论。

    对于N是奇数,检验中间点坐标是否合格,如果合格那就是他了,直接暴力算结果。如果不合格,我们上下左右四个点坐标一定合格(可以自己画图看看),算那四个点坐标,找最小的输出就行了。

    对于N是偶数,那么根据中位数定理,最小值是一段二维的区间。如果这个二维的区间缩成了一个点,用上面的思路处理就行了。否则这个区间一定包含合法的点。而且这个区间内的值是相同的,统计合法的点的数目,直接输出就行了。具体实现可以看代码。

    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    long long x[100010], y[100010];
    
    //最优解在一个点,如果那个点不合法,找他四个相邻的点
    
    long long calc(long long xx, long long yy)
    {
    	long long res = 0;
    	for (int i = 1; i <= n; i++)
    		res += abs(x[i] - xx) + abs(y[i] - yy);
    	return res;
    }
    
    //偶数
    long long calc_even(long long l, long long r)
    {
    	long long len = (r - l + 1);
    	if (len % 2 == 0)
    		return len / 2;
    	else
    	{
    		if ((l & 1) && (r & 1))
    			return len / 2;
    		else
    			return len / 2 + 1;
    	}
    }
    
    //奇数
    long long calc_odd(long long l, long long r)
    {
    	long long len = (r - l + 1);
    	if (len % 2 == 0)
    		return len / 2;
    	else
    	{
    		if ((l & 1) && (r & 1))
    			return len / 2 + 1;
    		else
    			return len / 2;
    	}
    }
    
    void work1()
    {
    	int mx = x[(n + 1) / 2], my = y[(n + 1) / 2];
    	if ((mx + my) & 1)
    	{
    		long long res[4];
    		res[0] = calc(mx - 1, my);
    		res[1] = calc(mx + 1, my);
    		res[2] = calc(mx, my - 1);
    		res[3] = calc(mx, my + 1);
    		sort(res, res + 4);
    		cout << res[0] / 2 << endl;
    		int t = 1;
    		if (res[0] == res[1])
    		{
    			t++;
    			if (res[1] == res[2])
    			{
    				t++;
    				if (res[2] == res[3])
    				{
    					t++;
    				}
    			}
    		}
    		cout << t << endl;
    	}
    	else
    	{
    		long long res = calc(mx, my);
    		cout << res / 2 << endl << 1 << endl;
    	}
    }
    
    
    void work0()
    {
    	long long x1 = x[n / 2], x2 = x[n / 2 + 1];
    	long long y1 = y[n / 2], y2 = y[n / 2 + 1];
    	//如果[x1, x2]或[y1, y2]区间长度大于1就钦定了
    	//当[x1, x2]和[y1, y2]都是一个点
    	//才用想上面那样特盘
    	if (x1 == x2 && y1 == y2)
    	{
    		if ((x1 + y1) & 1)
    		{
    			long long res[4];
    			res[0] = calc(x1 - 1, y1);
    			res[1] = calc(x1 + 1, y1);
    			res[2] = calc(x1, y1 - 1);
    			res[3] = calc(x1, y1 + 1);
    			sort(res, res + 4);
    			cout << res[0] / 2 << endl;
    			int t = 1;
    			if (res[0] == res[1])
    			{
    				t++;
    				if (res[1] == res[2])
    				{
    					t++;
    					if (res[2] == res[3])
    					{
    						t++;
    					}
    				}
    			}
    			cout << t << endl;
    		}
    		else
    		{
    			long long res = calc(x1, y1);
    			cout << res / 2 << endl << 1 << endl;
    		}
    	}
    	else
    	{
    		//否则这个二维区间内一定存在至少一个合法数字。
    		//现在任务是给定[x1, x2]和[y1, y2]求有多少合法数字。
    		//对于一个合法数字,一定是两个偶数或者两个奇数组成。
    		//所以只需要统计闭区间奇数和偶数的个数。
    		long long evenx = calc_even(x1, x2);
    		long long oddx = calc_odd(x1, x2);
    		long long eveny = calc_even(y1, y2);
    		long long oddy = calc_odd(y1, y2);
    		long long res = evenx * eveny + oddx * oddy;
    		long long ans = calc(x1, y1);
    		cout << ans / 2 << endl << res << endl;
    	}
    }
    
    int main()
    {
    	scanf("%d", &n);
    	for (int xx, yy, i = 1; i <= n; i++)
    	{
    		scanf("%d%d", &xx, &yy);
    		x[i] = xx + yy;
    		y[i] = xx - yy;
    	}
    	sort(x + 1, x + 1 + n);
    	sort(y + 1, y + 1 + n);
    	if (n & 1)
    		work1();
    	else
    		work0();
    	return 0;
    }
    

    C-分则能成

    牛牛刚开始有一个正整数n。每次操作牛牛可以选择一个自己有的数字x,把x分为两正整数y和z,需满足x=y+z,然后获得y*z的收益。 (当然,在这个过程中,牛牛会失去x这个数字,并且获得y和z这2个数字。)

    牛牛一共可以分k次,牛牛希望最大化这k次的收益之和。 因为分割的结果y和z是正整数,所以选择的x必须>=2。

    对于100%的数据,1 <= k < n <= 109 对于40%的数据,1 <= k < n <= 10 对于70%的数据,1 <= k < n <= 100

    Solution:(upd:所有的k改成了k+1)

    打表发现,我们把N拆成k+1个均匀的数,xjb合并即可。
    这些数的平均数是(displaystyle frac N {k+1})(废话)
    如果那个(displaystyle frac N {k+1})是整数,那就是k+1个这数字喽。
    如果(displaystyle frac N {k+1})不是一个整数,那么

    较小的数为(displaystyle leftlfloor frac N {k+1} ight floor),有(displaystyle {(k+1)}leftlceil frac N {k+1} ight ceil-N)个。

    较大的数为(displaystyle leftlceilfrac N {k+1} ight ceil),有(displaystyle N-{(k+1)}leftlfloorfrac N {k+1} ight floor)个。(by GMPotlc: 这tmd就是(Nmod(k+1))啊,你个sb)

    同理,xjb合并即可。

    合并的计算可以用分治,log级别。

    全程开long long

    #include <bits/stdc++.h>
    using namespace std;
    
    //合并k个x得到的exp
    //分治。。。log级别的
    long long merge(long long x, long long k)
    {
    	//一个合并个毛线
    	if (k == 1)
    		return 0;
    	if (k & 1)//k/2, k/2, 1
    	{
    		long long res = merge(x, k / 2);
    		long long yg = x * (k / 2);
    		return res * 2 + yg * yg + 2 * yg * x;
    	}
    	else
    	{
    		//k/2, k/2
    		long long res = merge(x, k / 2);
    		long long yg = x * (k / 2);
    		return res * 2 + yg * yg;
    	}
    }
    
    int main()
    {
    	long long n, k;
    	cin >> n >> k;
    	k++;
    	if (n % k == 0)
    	{
    		long long fuck = n / k;
    		cout << merge(fuck, k) << endl;
    	}
    	else
    	{
    		long long fuck1 = n / k, fuck2 = fuck1 + 1;
    		//向下取整,向上取整
    		long long t1 = k * fuck2 - n, t2 = n - k * fuck1;
    		long long res1 = merge(fuck1, t1);
    		long long res2 = merge(fuck2, t2);
    		long long tot1 = t1 * fuck1, tot2 = t2 * fuck2;
    		long long res3 = tot1 * tot2;
    		cout << res1 + res2 + res3 << endl;
    	}
    	return 0;
    }
    

    upd:dp打表程序,加一个#define csv就行

    #include <bits/stdc++.h>
    using namespace std;
    
    int f[110][110];
    
    int main()
    {
    	int n, k;
    	scanf("%d%d", &n, &k);
    	for (int x = 2; x <= n; x++)
    		for (int y = 1; y <= k; y++)
    		{
    			for (int i = 1; i < x; i++)//i, x - i
    				for (int j = 0; j < y; j++)//j, y - j - 1
    					f[x][y] = max(f[x][y], f[i][j] + f[x - i][y - j - 1] + i * (x - i));
    		}
    	printf("%d
    ", f[n][k]);
    #ifdef csv
    	freopen("data.csv", "w", stdout);
    	printf("he,");
    	for (int i = 0; i <= 100; i++)
    		printf("[%d],", i);
    	printf("
    ");
    	for (int i = 0; i <= 100; i++)
    	{
    		printf("-%d-,", i);
    		for (int j = 0; j <= 100; j++)
    			printf("%d,", f[i][j]);
    		printf("
    ");
    	}
    #endif
    	return 0;
    }
    

    D-戴德兰

    改了题面就是水题了

    #include <bits/stdc++.h>
    using namespace std;
     
    int n, c, d, a[10010];
     
    int main()
    {
        scanf("%d%d%d", &n, &c, &d);
        c += d;
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        sort(a + 1, a + 1 + n);
        for (int i = 1; i <= n; i++)
        {
            if (c - a[i] < 0)
            {
                printf("%d
    ", i - 1);
                break;
            }
            c -= a[i];
        }
        return 0;
    }
    
  • 相关阅读:
    Effective C++第三遍
    SQL基础教程
    hibernate 数据关联多对多
    hibernate 数据关联一对一
    hibernate 数据关联一对多
    hibernate Criteria查询
    hibernate HQL查询
    hibernate 持久化对象的生命周期
    hibernate的配置
    微博登录
  • 原文地址:https://www.cnblogs.com/oier/p/9689742.html
Copyright © 2011-2022 走看看