牛客等级之题N2(持续更新)

Powered by:AB_IN 局外人

真的挺适合我这种小白的。

等级之题N2(8.3)

大圆的半径最小=红色面积最大=两个小半圆直径都是大半圆的半径。

import math
s=int(input())
a=(4*s/math.pi)**0.5
print(f'{a:.3f}')

拯救单身狗(8.4)

#include
using namespace std;
const int maxn=1000010;
int a[maxn],t,x;
int main()
{
    cin>>t;
    while(t--)
    {
        int maxm=-0x3f3f3f,flag=0;
        memset(a, 0, sizeof(a));
        while(cin>> x && x!=0) {a[x]++;maxm=max(x,maxm);}
        for(int i=1;i<=maxm;i++){
            if(a[i]&1){
                cout<<"No"<<endl;
                flag=1;
                break;
            }
        }
        if(!flag) cout<<"Yes"<<endl;
    }
}

做题(8.5)

#include
using namespace std;
typedef long long ll;
const int maxn=5e5+10;
ll n,m,a[maxn],cnt;
namespace IO{
    char ibuf[1<<21],*ip=ibuf,*ip_=ibuf;
    char obuf[1<<21],*op=obuf,*op_=obuf+(1<<21);
    inline char gc(){
        if(ip!=ip_)return *ip++;
        ip=ibuf;ip_=ip+fread(ibuf,1,1<<21,stdin);
        return ip==ip_?EOF:*ip++;
    }
    inline void pc(char c){
        if(op==op_)fwrite(obuf,1,1<<21,stdout),op=obuf;
        *op++=c;
    }
    inline ll read(){
        register ll x=0,ch=gc(),w=1;
        for(;ch<'0'||ch>'9';ch=gc())if(ch=='-')w=-1;
        for(;ch>='0'&&ch<='9';ch=gc())x=x*10+ch-48;
        return w*x;
    }
    template<class I>
    inline void write(I x){
        if(x<0)pc('-'),x=-x;
        if(x>9)write(x/10);pc(x%10+'0');
    }
    class flusher_{
    public:
        ~flusher_(){if(op!=obuf)fwrite(obuf,1,op-obuf,stdout);}
    }IO_flusher;
}
using namespace IO;
int main()
{
    n=read();m=read();
    for(int i=1;i<=n;i++)
        a[i]=read();
    sort(a+1,a+1+n);
    for(int i=1;i<=n;i++)
    {
        if(a[i]<=m)
        {
            m-=a[i];
            cnt++;
        }
    }
    write(cnt);
}

Rinne Loves Study(8.6)

思维题。
用数组的一维记录行或列的操作,另一维记录行列数
就用一个数来记录这一行或者这一列的状态,不用写一个循环了。

#include
using namespace std;
int a[3][100100],n,m,t,x,op1;
int main()
{
    cin>>n>>m>>t;
    for(int i=1;i<=t;i++){
        cin>>op1>>x;
        a[op1][x]=i;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<max(a[1][i],a[2][j])<<" ";
        }
        cout<<endl;
    }
    return 0;
}

小sun的假期(8.10)

差不多是括号序列的题。
将括号排个序,然后维护未覆盖区域的最大值即可。

#include
using namespace std;
#define ll long long
const int N = 1e5+5;
pair<int,int> p[N];
int main() {
    int n,m,l,r;
    cin >> n >> m;
    for(int i=1;i<=m;i++) {
        cin >> l >> r;
        p[i] = {l,r};
    }
    sort(p+1,p+m+1);
    int maxn = 0,now = 0;
    for(int i=1;i<=m;i++) {
        if(now < p[i].first) {
            maxn = max(maxn,p[i].first - now - 1);
        }
            now = max(now,p[i].second);
    }
    maxn = max(maxn,n-now);//最后还有一段
    cout << maxn;
    return 0;
}

数数(8.11)

记录一下这两个符号 ∏ \prod ∑ \sum
∑ i = 1 n i = n ∗ ( n + 1 ) 2 {\sum_{i=1}^n i=} \frac{n*(n+1)} {2} i=1ni=2n(n+1)

∑ i = 1 n ∑ j = 1 n i ∗ j = ∑ i = 1 n i ∑ j = 1 n j {\sum_{i=1}^n \sum_{j=1}^n i*j=} {\sum_{i=1}^ni \sum_{j=1}^n j} i=1nj=1nij=i=1nij=1nj
∏ i = 1 n i = n ! {\prod_{i=1}^n i=} n! i=1ni=n!

∏ i = 1 n ∏ j = 1 n i ∗ j = ∏ i = 1 n i n ∏ j = 1 n j {\prod_{i=1}^n \prod_{j=1}^n i*j=} {\prod_{i=1}^n i^n \prod_{j=1}^n j} i=1nj=1nij=i=1ninj=1nj
所以
∑ i = 1 n ∑ j = 1 n i ∗ j = ∑ i = 1 n i ∑ j = 1 n j = ∑ i = 1 n i ∗ n ∗ ( n + 1 ) 2 = n ∗ ( n + 1 ) 2 ∗ ∑ i = 1 n i = ( n ∗ ( n + 1 ) 2 ) 2 \begin{aligned} {\sum_{i=1}^n \sum_{j=1}^n i*j} &={\sum_{i=1}^ni \sum_{j=1}^n j}\\&={\sum_{i=1}^n i}*\frac{n*(n+1)} {2}\\&=\frac{n*(n+1)} {2}*{\sum_{i=1}^n i}\\&=(\frac{n*(n+1)} {2})^2 \end{aligned} i=1nj=1nij=i=1nij=1nj=i=1ni2n(n+1)=2n(n+1)i=1ni=(2n(n+1))2

∏ i = 1 n ∏ j = 1 n i ∗ j = ∏ i = 1 n i n ∏ j = 1 n j = ∏ i = 1 n i n ( n ! ) = ( n ! ) n ∏ i = 1 n i n = ( n ! ) n ∗ ( n ! ) n = ( n ! ) 2 n \begin{aligned} {\prod_{i=1}^n \prod_{j=1}^n i*j}&= {\prod_{i=1}^n i^n \prod_{j=1}^n j}\\&= {\prod_{i=1}^n i^n (n!)}\\&=(n!)^n{\prod_{i=1}^n i^n }\\&=(n!)^n*(n!)^n\\&=(n!)^{2n} \end{aligned} i=1nj=1nij=i=1ninj=1nj=i=1nin(n!)=(n!)ni=1nin=(n!)n(n!)n=(n!)2n

#include
using namespace std;
typedef unsigned long long ll;
ll t,n;

const ll mod=998244353;
ll qm (ll a, ll b ,ll c){
    ll ret=1%c;
    while(b){
        if(b&1)
            ret=ret*a%c;
        a=a*a%c;
        b=b>>1;
    }
    return ret;
}
ll jc(ll n){
    ll ans=1;
    for(int i=2;i<=n;i++){
        ans=(ans*i)%mod;
    }
    return ans;
}
int main()
{
    cin>>t;
    while(t--){
        cin>>n;
        ll ans1=qm((n*(n+1)/2)%mod,2,mod);
        ll ans2=qm(jc(n),2*n%mod,mod);
        cout<<ans1<<" "<<ans2<<endl;
    }
    return 0;
}

矩阵消除游戏(8.11N1)

  • 二进制枚举例题,数据比较小, 1 ≤ n , m ≤ 15 1≤n,m≤15 1n,m15.
  • 可以先根据贪心枚举出行的选取情况,选一行,选两行……,然后先给列进行大小排序,根据行的选取情况,来决定是否选列,选几个列。
  • cin cout时, d e f i n e define define一个 I O S IOS IOS即可
  • #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include
using namespace std;
typedef long long ll;
#define IOS  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll a[20][20],sum[20],b[20][20];
bool cmp(int a,int b){return a>b;}
ll s,n,m,t,ans=-0x3f;
int main()
{
    IOS;
    cin>>n>>m>>t;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j],s+=a[i][j];
    if(t>=min(n,m)){cout<<s<<endl;return 0;}
    for(int i=0;i<(1<<n);i++){
        ll tmp=0;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                b[i][j]=a[i][j];
        int p=0;
        for(int j=0;j<n;j++)
            if(i&(1<<j)){
                p++;
                for(int k=1;k<=m;k++)
                    tmp+=b[j+1][k],b[j+1][k]=0;
            }
        if(p>t)continue;
        for(int j=1;j<=m;j++){
            sum[j]=0;
            for(int h=1;h<=n;h++)
                sum[j]+=b[h][j];
        }
        sort(sum+1,sum+1+m,cmp);
        for(int j=1;j<=t-p;j++)
            tmp+=sum[j];
        ans=max(ans,tmp);
    }
    cout<<ans<<endl;
}

小w的a+b问题(8.12)

n = − 1 n=-1 n=1时构造不出来。 i n t int int的下限是 − 2147483647 -2147483647 2147483647,由于n是负数,用n一减,就成正的了。

#include
int n;
int main()
{
    scanf("%d",&n);
	if(n==-1) puts("No solution");
	else printf("2147483647 %d\n",n-2147483647);
}

小w的a=b问题(8.12N1)

  • 一、遇到需要多次用阶乘的题,不用写个函数,直接打个表就行了。
  • 二、遇到最后输出不是数,而是一个判断结果时。可以对数随意取模,这样更快。比如这个题就是判断两个数是否相等,取模就可以了
lst=[1,1]
mod=2**64-1
for i in range(2,100001):
  lst.append(lst[i-1]*i%mod)
for _ in range(int(input())):
  x=1;y=1
  a,b=map(int ,input().split())
  l1=list(map(int,input().split()))
  l2=list(map(int,input().split()))
  for i in l1:
    x=x*lst[i]%mod
  for i in l2:
    y=y*lst[i]%mod
  if(x==y):
    print("equal")
  else:
    print("unequal")

斐波那契(8.13)

简单的矩阵乘法

#include 
using namespace std;
const int MAX = 4;
const int mod=1e9+7;
typedef long long ll;
typedef struct{
    ll m[MAX][MAX];
}Matrix;

Matrix P;//构造出的矩阵

Matrix matrixmul(Matrix a,Matrix b) //矩阵乘法
{
    int i,j,k;
    Matrix c;
    for (i = 0 ; i < MAX; i++)
        for (j = 0; j < MAX;j++)
        {
            c.m[i][j] = 0;
            for (k = 0; k < MAX; k++)
                c.m[i][j] =(c.m[i][j]+(a.m[i][k]*b.m[k][j]))%mod;
            c.m[i][j] %=mod;
        }
    return c;
}

Matrix quickpow(Matrix m , ll n)
{
    Matrix b;//单位矩阵在这构造也可以
    for(int i=0;i<MAX;i++)
        for(int j=0;j<MAX;j++)
        {
            if(i==j)b.m[i][j]=1;
            else b.m[i][j]=0;
        }
    while (n >= 1)
    {
        if (n & 1)
                b = matrixmul(b,m);
        n = n >> 1;
        m = matrixmul(m,m);
    }
    return b;
}
ll n,x,y,ans;
int main()
{
    while(cin>>n){
        ans=0;
        P={1,1,0,0,
           0,1,1,2,
           0,1,0,0,
           0,1,0,1};
        Matrix tmp=quickpow(P,n-1);
        for(int i=0;i<4;i++){
            ans=(ans+tmp.m[0][i])%mod;
        }
        printf("%lld\n",ans%mod);
    }

    return 0;
}

也可以推出公式。
∑ i = 1 n f n 2 = f n ∗ f n + 1 \sum_{i=1}^n{f_n^2}=f_n*f_{n+1} i=1nfn2=fnfn+1

你可能感兴趣的:(ACM)