2021-01-21 灵动ICPC集训

2021-01-21 灵动ICPC集训

学习内容:数学初步、排序、简单排序算法

1.Necklace

在线测试:UVA 11001

题目

The people of a certain tribe produce circular ceramic discs with equal diameter by some rare clay. A necklace is formed by connecting one or more discs. The figure below shows a necklace made with 4discs. Its length is 4 times the diameter of each disc.
在这里插入图片描述
The thickness of each disc is fixed. The diameter D and the volume of clay used V has the following relationship:
在这里插入图片描述
where V0 is the volume consumed in the baking process, in the same unit of V . When V ≤ V0, no ceramic discs can be made. As an example, let Vtotal = 10, V0 = 1. If we use it to make 1 disc, V = Vtotal = 10, D = 0.9. If we divide the clay into 2 parts, the volume of each part V = Vtotal/2 = 5,
and diameter of each disc formed is D′ = 0.3√5 − 1 = 0.6, thus the length of necklace formed this way is 1.2.As per the above example, it is obvious that the lengths of necklaces differ as the number of discs made changes. Please write a program that computes the number of discs one should make so that the necklace formed is the longest.
Input
Each line of input contains two numbers, Vtotal (0 < Vtotal ≤ 60000) and V0 (0 < V0 ≤ 600), as defined above. Input ends with a case where Vtotal = V0 = 0.
Output
Each line of output should give the number of discs one should make so that the necklace formed is the longest. If this number is not unique, or no necklaces can be formed at all, output ‘0’ instead.
Sample Input
10 1
10 2
0 0
Sample Output
5
0

思考过程

在这里插入图片描述

源代码

#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
    double vt,vo;
    while(~scanf("%lf%lf",&vt,&vo))
    {
        if(vt==0||vo==0)
        break;
        else if(vt<=vo)
        {
            printf("0\n");
        }
        else if(vt<=2*vo)
        {
            printf("1\n");
        }
        else
        {
            double m=vt/2*vo;
            if(m-(int)m==0.5)
            {
                printf("0\n");
            }
            else if(m-(int)m<0.5)
            {
                printf("%d\n",(int)m);
            }
            else
            {
                printf("%d\n",(int)m+1);
            }
        }
    }
    return 0;
}

2.Bode Plot

题目来源:ACM Greater New York 2001

题目

Consider the AC circuit below. We will assume that the circuit is in steady-state. Thus, the voltage at nodes 1 and 2 are given by v1 = VS coswt and v2 = VRcos (wt + q ) where VS is the voltage of the source, w is the frequency (in radians per second), and t is time. VR is the magnitude of the voltage drop across the resistor, and q is its phase.
在这里插入图片描述
You are to write a program to determine VR for different values of w. You will need two laws of electricity to solve this problem. The first is Ohm’s Law, which states v2 = iR where i is the current in the circuit, oriented clockwise. The second is i = C d/dt (v1-v2) which relates the current to the voltage on either side of the capacitor. "d/dt"indicates the derivative with respect to t.
Input
The input will consist of one or more lines. The first line contains three real numbers and a non-negative integer. The real numbers are VS, R, and C, in that order. The integer, n, is the number of test cases. The following n lines of the input will have one real number per line. Each of these numbers is the angular frequency, w.
Output
For each angular frequency in the input you are to output its corresponding VR on a single line. Each VR value output should be rounded to three digits after the decimal point.
Sample Input
1.0 1.0 1.0 9
0.01
0.031623
0.1
0.31623
1.0
3.1623
10.0
31.623
100.0
Sample Output
0.010
0.032
0.100
0.302
0.707
0.953
0.995
1.000
1.000

思考过程

在这里插入图片描述

源代码

#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;
int main()
{
    double Vs,R,C;
    int n;
    scanf("%lf%lf%lf%d",&Vs,&R,&C,&n);
    while(n--)
    {
        double W;
        scanf("%lf",&W);
        double R2,C2,W2;
        R2=pow(R,2);C2=pow(C,2);W2=pow(W,2);
        double sin;
        sin=sqrt(1/(R2*C2*W2+1));
        double Vr;
        Vr=R*C*W*Vs*sin;
        printf("%.3lf\n",Vr);
    }
    return 0;
}

3.Symmetric Matrix (超时)

试题来源:Huge Easy Contest, 2007

题目

You‘re given a square matrix M. Elements of this matrix are Mij : {0 < i < n, 0 < j < n}. In thisproblem you’ll have to find out whether the given matrix is symmetric or not. Definition: Symmetric matrix is such a matrix that all elements of it are non-negative and symmetric with relation to the center of this matrix. Any other matrix is considered to be non-symmetric.
For example:
M =
5 1 3
2 0 2
3 1 5
is symmetric
M =
5 1 3
2 0 2
0 1 5
is not symmetric, because 3!=0
All you have to do is to find whether the matrix is symmetric or not. Elements of a matrix given in the input are −2^32 ≤ Mij ≤ 2 ^32 and 0 < n ≤ 100.
Input
First line of input contains number of test cases T ≤ 300. Then T test cases follow each described in the following way. The first line of each test case contains n – the dimension of square matrix. Then n lines follow each of then containing row i. Row contains exactly n elements separated by a space character. j-th number in row i is the element Mij of matrix you have to process.
Output
For each test case output one line ‘Test #t: S’. Where t is the test number starting from 1. Line S
is equal to ‘Symmetric’ if matrix is symmetric and ‘Non-symmetric’ in any other case.
Sample Input
2
N = 3
5 1 3
2 0 2
3 1 5
N = 3
5 1 3
2 0 2
0 1 5
Sample Output
Test #1: Symmetric.
Test #2: Non-symmetric.

思考过程

给出的方阵用二维数组M[100][100]表示。对称矩阵的所有元素都是非负的,并且相对于这个矩阵的中心是对称的,所以,如果有元素是负数,或者存在相对于中心不对称,即M[i][j] !=M[N-1-i][N- 1-j],则给出的方阵不是对称的

源代码

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
 
using namespace std;
 
long long M[105][105];
 
int main()
{
    int T,n;
    char ch;
    while(~scanf("%d",&T))
        for(int t=1;t<T+1;++t)
        {
            getchar();
            scanf("N = %d",&n);
             int i,j;
            for(i=0;i<n;i++)
               for(j=0;j<n;j++)
                   scanf("%lld",&M[i][j]);
            int flag
            for(i=0;i<n;i++)
            {
               for(j=0;j<n;j++)
                   if(M[i][j]<0||M[i][j]!=M[n-1-i][n-1-j])
                     {
                         flag=0;
                        break;
                    }
                    if(!flag) break;
              }
               if(flag)
               printf("Test #%d: Symmetric.\n",t);
              else
              printf("Test #%d: Non-symmetric.\n",t);
        }
    return 0;
}

4.Homogeneous Squares (超时)

试题来源:Ulm Local 2006

题目

Assume you have a square of size n that is divided into n × n positions just as a checkerboard. Two positions (x1, y1) and (x2, y2), where 1 ≤ x1, y1, x2, y2 ≤ n, are called “independent” if they occupy different rows and different columns, that is, x1 ≠ x2 and y1 ≠ y2. More generally, n positions are called independent if they are pairwise independent. It follows that there are n! different ways to choose n independent positions.

Assume further that a number is written in each position of such an n × n square. This square is called “homogeneous” if the sum of the numbers written in n independent positions is the same, no matter how the positions are chosen. Write a program to determine if a given square is homogeneous!

Input
The input contains several test cases.

The first line of each test case contains an integer n (1 ≤ n ≤ 1000). Each of the next n lines contains n numbers, separated by exactly one space character. Each number is an integer from the interval [−1000000, 1000000].

The last test case is followed by a zero.
Output
For each test case output whether the specified square is homogeneous or not. Adhere to the format shown in the sample output.
Sample Input
2
1 2
3 4
3
1 3 4
8 6 -2
-3 4 0
0
Sample Output
homogeneous
not homogeneous

思考过程

在这里插入图片描述
由这一局部解递推出规律:对于一个n×n方阵,只要它的所有的(n-1)×(n-1)子方阵homogeneous的,则该n×n方阵是homogeneous的;进一步递推可得,只要该n×n方阵的所有的2×2的子方阵符合两对角线相加相等,该该n×n方阵是homogeneous的。

源代码

#include<stdio.h>
int a[100][100];
int main()
{
    int n,i,j;
    while(scanf("%d",&n))
    {
        if(n==0) break;
        int flag=1;
        for(i=1;i<n+1;i++)
            for(j=1;j<n+1;j++)
            scanf("%d",&a[i][j]);
         for(i=1;i<n;i++)
            for(j=1;j<n;j++)
            {
                if(a[i][j]+a[i+1][j+1]!=a[i][j+1]+a[i+1][j])
                {
                    flag=0;
                    break;
                }
            }
        if(flag)
            printf("homogeneous\n");
        else
            printf("not homogeneous\n");
    }
    return 0;
}

5.To the Max

试题来源:ACM Greater New York 2001

题目

Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle. As an example, the maximal sub-rectangle of the array:

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
is in the lower left corner:

9 2
-4 1
-1 8
and has a sum of 15.
Input
The input consists of an N * N array of integers. The input begins with a single positive integer N on a line by itself, indicating the size of the square two-dimensional array. This is followed by N^2 integers separated by whitespace (spaces and newlines). These are the N^2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in the second row, left to right, etc. N may be as large as 100. The numbers in the array will be in the range [-127,127].
Output
Output the sum of the maximal sub-rectangle.
Sample Input
4
0 -2 -7 0 9 2 -6 2
-4 1 -4 1 -1

8 0 -2
Sample Output
15

思考过程

在这里插入图片描述
在这里插入图片描述
转载—>最大子矩阵和讲解

源代码

#include<cstdio>
#include<string.h>
#include<string>
#include<iostream>
using namespace std;

#define maxn 105
#define inf 0x3f3f3f3f

int array[maxn][maxn];
int f[maxn][maxn][maxn];

int main()
{
    int n;cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++){scanf("%d", &array[i][j]);}
    }
    memset(f, 0, sizeof(f));
    int ans=-inf;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int sum=0;
            for(int k=j;k<=n;k++)
            {
                sum+=array[i][k];
                f[i][j][k]=max(f[i-1][j][k]+sum,sum);
                ans=max(ans,f[i][j][k]);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
//思路简述:这是一个可以化为选出最大子序列的问题,首先对一行进行选取,选出以当前数结束的序列的和的最大值
//然后将每一行的每一列数逐次加起来,形成一个新的序列,再一次进行选择,max不断被取缔
#include<stdio.h>
#include<string.h>
 
#define MAXN 105
#define INF -1000
 
int srow[MAXN];
int num[MAXN][MAXN];
 
int main(int argc,char *argv[])
{
	int n;
	int i;
	int j;
	int k;
    int rmax=INF;
	int nsum;
 
    scanf("%d",&n);//输入矩阵大小
 
	memset(num,0,sizeof(num));
 
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=n;j++)
			scanf("%d",&num[i][j]);//输入矩阵各点的值
	}
 
	for(i=1;i<=n;i++)
	{
		memset(srow,0,sizeof(srow));
		for(j=i;j<=n;j++)
		{
			nsum=0;//每一次清零
			for(k=1;k<=n;k++)
			{
				srow[k]+=num[j][k];//将两行的同列相加
				if(nsum>0)          //将同列相加的数看作是一维数组求最大子序列和
					nsum+=srow[k];
				else
					nsum=srow[k];
				if(nsum>rmax)
					rmax=nsum;//更换最大值
			}
		}
	}
 
	printf("%d\n",rmax);
	return 0;
}

(代码摘自:LDan508【算法设计与分析】To the max)

6.Who’s in the Middle

试题来源:USACO 2004 November

题目

FJ is surveying his herd to find the most average cow. He wants to know how much milk this ‘median’ cow gives: half of the cows give as much or more than the median; half give as much or less.

Given an odd number of cows N (1 <= N < 10,000) and their milk output (1…1,000,000), find the median amount of milk given such that at least half the cows give the same amount of milk or more and at least half give the same or less.
Input

  • Line 1: A single integer N

  • Lines 2…N+1: Each line contains a single integer that is the milk output of one cow.
    Output

  • Line 1: A single integer that is the median milk output.
    Sample Input
    5
    2
    4
    1
    3
    5
    Sample Output
    3

源代码

#include<iostream>
#include<cstdio>
#define A 1005
using namespace std;
int main()
{
    int N;
    int cow[A];
    scanf("%d",&N);
    int i,t,v,m;
    for(i=0;i<N;i++)
    {
        cin>>cow[i];
    }
    int n;
    for(v=0;v<N;v++)
    {
        n=cow[v];
        for(i=v+1;i<N;i++)
        {
            if(n>cow[i])
            {
               t=cow[i];
               cow[i]=cow[v];
               cow[v]=t;
            }
        }
    }
        printf("%d",cow[N/2]);
    return 0;
}

7.Train Swapping

试题来源:ACM North Western European Regional Contest 1994

题目

At an old railway station, you may still encounter one of the last remaining “train swappers”. A train swapper is an employee of the railroad, whose sole job it is to rearrange the carriages of trains.Once the carriages are arranged in the optimal order, all the train driver has to do, is drop the
carriages off, one by one, at the stations for which the load is meant.
The title “train swapper” stems from the first person who performed this task, at a station close to a railway bridge. Instead of opening up vertically, the bridge rotated around a pillar in the center ofthe river. After rotating the bridge 90 degrees, boats could pass left or right.
The first train swapper had discovered that the bridge could be operated with at most two carriages on it. By rotating the bridge 180 degrees, the carriages switched place, allowing him to rearrange the carriages (as a side effect, the carriages then faced the opposite direction, but train carriages can move either way, so who cares).
Now that almost all train swappers have died out, the railway company would like to automate their operation. Part of the program to be developed, is a routine which decides for a given train the least number of swaps of two adjacent carriages necessary to order the train. Your assignment is to create that routine.
Input
The input contains on the first line the number of test cases (N). Each test case consists of two input lines. The first line of a test case contains an integer L, determining the length of the train (0 ≤ L ≤ 50).The second line of a test case contains a permutation of the numbers 1 through L, indicating the current order of the carriages. The carriages should be ordered such that carriage 1 comes first, then 2, etc.with carriage L coming last.
Output
For each test case output the sentence: ‘Optimal train swapping takes S swaps.’ where S is an
integer.
Sample Input
3
3
1 3 2
4
4 3 2 1
2
2 1
Sample Output
Optimal train swapping takes 1 swaps.
Optimal train swapping takes 6 swaps.
Optimal train swapping takes 1 swaps.

思考过程

输入列车的排列次序a[1]‥a[m]后,对a[ ]进行递增排序,在排序过程中数据互换的次数即为问题解。由于m的上限仅为50,因此使用冒泡排序亦满足时效要求。

源代码

#include<stdio.h>
int main()
{
    int N;
    scanf("%d",&N);
    while(N--)
    {
        int jsq=0,n,t;
        scanf("%d",&n);
        int i,j,a[n];
        for(i=0;i<n;i++)
        {
    	scanf("%d",&a[i]);
        }
        for(i=0;i<n-1;i++)
        {
            for(j=0;j<n-1-i;j++)
            {
                if(a[j]>a[j+1])
                {
                    t=a[j+1];
                    a[j+1]=a[j];
                    a[j]=t;
                    jsq++;
                }
            }
        }
    printf("Optimal train swapping takes %d swaps.\n",jsq);
    }
    return 0;
}

8.DNA Sorting

试题来源:ACM East Central North America 1998

题目

One measure of "unsortedness’’ in a sequence is the number of pairs of entries that are out of order with respect to each other. For instance, in the letter sequence "DAABEC’’, this measure is 5, since D is greater than four letters to its right and E is greater than one letter to its right. This measure is called the number of inversions in the sequence. The sequence "AACEDGG’’ has only one inversion (E and D)—it is nearly sorted—while the sequence "ZWQM’’ has 6 inversions (it is as unsorted as can be—exactly the reverse of sorted).

You are responsible for cataloguing a sequence of DNA strings (sequences containing only the four letters A, C, G, and T). However, you want to catalog them, not in alphabetical order, but rather in order of "sortedness’’, from "most sorted’’ to "least sorted’’. All the strings are of the same length.
Input
The first line contains two integers: a positive integer n (0 < n <= 50) giving the length of the strings; and a positive integer m (0 < m <= 100) giving the number of strings. These are followed by m lines, each containing a string of length n.
Output
Output the list of input strings, arranged from "most sorted’’ to "least sorted’’. Since two strings can be equally sorted, then output them according to the orginal order.
Sample Input
10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT
Sample Output
CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA

思考过程

“最多已排序”的串指的是串中逆序对数最少的串;而串中逆序对数最多的串就是所谓的“最少已排序”的串。所以设DNA序列为字符串数组s,其中第i个DNA串为s[i];逆序对数为f[i],1≤i≤m。 首先,使用冒泡排序,统计每个DNA串的逆序对数f[i];然后,使用插入排序,按逆序对数递增排序s;最后,输出s[1]‥s[m]。

源代码

#include<stdio.h>
#include<string.h>

#define M 200
struct dna
{
	char c[M];
	int ans;
}d[M],t;
int main()
{
	int n,m,i,j,k;
	scanf("%d%d",&n,&m);
	for(i=0;i<m;i++)
	{
		scanf("%s",d[i].c);
		d[i].ans=0;
		for(j=0;j<n;j++)
		{
			for(k=j;k<n;k++)
			if(d[i].c[j]>d[i].c[k])
				d[i].ans++;
		}
	}

	for(i=0;i<m;i++)
		for(j=i;j<m;j++)
		{
			if(d[i].ans>d[j].ans)
			{
				t=d[i];
				d[i]=d[j];
				d[j]=t;
			}
		}

	for(i=0;i<m;i++)
	{
		printf("%s\n",d[i].c);
	}
}

排序问题:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值