寒假集训第三期Day4

本文通过四个具体的编程实例,探讨了如何运用欧几里得算法、二次函数极值、交流电路分析和矩阵对称性判断来解决问题。在每个案例中,都详细介绍了问题背景、解题思路及代码实现。这些实例覆盖了数学和计算机科学的基础知识,旨在展示解决这类问题的通用方法。
摘要由CSDN通过智能技术生成

今天也是在做题,写了几道比较简单的题目,自信一下子回来了。(虽然我很清楚是题目比较简单再加上老师讲过)
Integer division between a dividend n and a divisor d yields a quotient q and a remainder r. q is the integer which maximizes q ∗ d
such that q ∗ d ≤ n and r = n − q ∗ d.
For any set of integers there is an integer d such that each of the
given integers when divided by d leaves the same remainder.
Input
Each line of input contains a sequence of nonzero integer numbers
separated by a space. The last number on each line is 0 and this
number does not belong to the sequence. There will be at least 2 and
no more than 1000 numbers in a sequence; not all numbers occuring
in a sequence are equal. The last line of input contains a single 0
and this line should not be processed.
Output
For each line of input, output the largest integer which when divided into each of the input integers
leaves the same remainder.
Sample Input
701 1059 1417 2312 0
14 23 17 32 122 0
14 -22 17 -31 -124 0
0
Sample Output
179
3
3
这题就是欧几里得,非常明显,没什么好讲的。

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<bits/c++io.h>
using namespace std;

int GDA(int a,int b){
    if(b==0) return a;
    else return GDA(b,a%b);
}

inline int Abs(int x){
    if(x>=0) return x;
    if(x<0) return -x;
}

int main(int argc,char const*argv[]){
    int f[10005];
    int count;
    while(1){
        for(int i=0;;i++){
            scanf("%d",&f[i]);
            if(f[i]==0){
                count=i;
                break;
            }
        }
        if(f[0]==0) break;
        for(int i=0;i<count-1;i++){
            f[i]=f[i]-f[i+1];
        }
        int ans=f[0];
        for(int i=0;i<count-1;i++){
            if(f[i]==0) ans=GDA(ans,ans);
            else ans=GDA(f[i],ans);
        }
        printf("%d\n",Abs(ans));
    }
    return 0;
}

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 4
discs. 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:
p(x) = {
0.3

V − V0 if V > V0
0 if V ≤ V0
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

思维题,推导就行:
一共n个圆环,圆环的直径为D,那么项链长f(n)=nD;然后把D的式子代进来,D=0.3sqrt(V/n-V0),然后根号会影响结果,所以开平方,f(n)/0.3=nsqrt(V/n-V0),f(n)/0.3的平方=nn*(V/n-V0);设一个函数g(n)=f(n)/0.3的平方=nn(V/n-V0),题目就转变成让g(n)最大。这是关于n的二次函数,直接求导求极值,g’(n)=V-2nV0,让g’(n)=0,求出n的表达式。
要注意就是n求出来是小数,因为二次函数的图像与x轴有两个交点,所以要判断是向下取整还是向上取整,如果n-n取整等于0.5,说明有两个解,答案不唯一,输出0。
还要注意就是V不能小于V0。
下面是代码

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<bits/c++io.h>
using namespace std;

int main(int argc,char const*argv[]){
    double V,V0;
    while(scanf("%lf%lf",&V,&V0)!=EOF){
        if(V==0&&V0==0) break;
        if(V<=V0) printf("0\n");
        else {
            double a;
            a=V/(2.0*V0);
            int n=(int)a;
            if(a-n==0.5) printf("0\n");
            if(a-n>0.5) printf("%d\n",n+1);
            if(a-n<0.5) printf("%d\n",n);
        }
    }
    return 0;
}

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<cstring>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<bits/c++io.h>
using namespace std;

int main(int argc,char const*argv[]){
    double Vs,R,C;
    int n;
    scanf("%lf%lf%lf%d",&Vs,&R,&C,&n);
    while(n--){
        double w;
        scanf("%lf",&w);
        double sin;
        sin=sqrt(1/(R*R*C*C*w*w+1));
        double Vr=R*C*w*Vs*sin;
        printf("%.3f\n",Vr);
    }
    return 0;
}

You‘re given a square matrix M. Elements of this matrix are Mij : {0 < i < n, 0 < j < n}. In this
problem 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.
直接for循环枚举!

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<bits/c++io.h>
using namespace std;

int main(int argc,char const*argv[]){
    int T;
    long long M[105][105];
    while(scanf("%d",&T)!=EOF){
    int t=1;
    while(T--){
        int n,flag=1;
        getchar();
        scanf("N = %d",&n);
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                scanf("%lld",&M[i][j]);
                if(M[i][j]<0) flag=0;
            }
        }
        if(flag==0){
            printf("Test #%d: Non-symmetric.\n",t);
            t++;
        }
        else{
            for(int i=0;i<n/2+1;i++){
                for(int j=0;j<n;j++){
                    if(M[i][j]!=M[n-1-i][n-1-j]){
                        flag=0;
                        break;
                    }
                }
                if(flag==0) break;
            }
            if(flag==0) printf("Test #%d: Non-symmetric.\n",t);
            else printf("Test #%d: Symmetric.\n",t);
            t++;
        }
    }
    }
    return 0;
}

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

8 0 -2
Sample Output
15
就是求最大子矩阵,可以用矩阵合并把二维数组变成一维数组。三个for循环套。
第一轮先是从第一行开始让第一行和自己合并,然后1,2行合并,然后1,2,3行合并……
第二轮从第二行开始,先和自己合并,然后2,3行合并,2,3,4行合并……
每次合并的时候求出这个一位数组的最大子序列,然后用max记录,每一轮的最大子序列大于max就让max等于这个最大子序列。
下面是代码

#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<bits/c++io.h>
using namespace std;
int vans[1005][1005];
long long a[105];
int maxi;

int maxarray(long long x[],int n){
    int m=maxi;
    int temp=-1;
    for(int i=0;i<n;i++){
        if(temp>0) temp+=x[i];
        else temp=x[i];
        if(temp>m)
            m=temp;
    }
    return m;

}

int main(int argc,char const*argv[]){
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            scanf("%d",&vans[i][j]);
        }
    }
    maxi=vans[0][0];
    int temp;
    for(int i=0;i<n;i++){
        memset(a,0,sizeof(a));
        for(int j=i;j<n;j++){
            for(int k=0;k<n;k++){
                a[k]+=vans[j][k];
            }
            temp=maxarray(a,n);
            if(temp>maxi)
                maxi=temp;
        }
    }
    printf("%d\n",maxi);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值