天天看點

牛客OI賽制測試賽2

比賽連結:點我

連結:https://www.nowcoder.com/acm/contest/185/A

來源:牛客網

題目描述

給出一個二進制組(A,B)

求出無序二進制組(a,b) 使得(a|A,b|B)的組數

無序意思就是(a,b)和(b,a) 算一組.

輸入描述:

第一行資料組數 T(1≤T≤10000)

接下來T行,每行兩個正整數 A,B(1≤A,B≤10000)

輸出描述:

共T行,每行一個結果

組合,求A和B的因子個數,乘起來,減去他們最大公約數的因子的組合數,組合數為n*(n-1)/2

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
int num[maxn];
int count(int n)///求因子的個數
{
    int s=1;///記錄總共的素因子的個數
    for(int i=2;i*i<=n;i++)
        if(n%i==0)
    {
        int a=0;///記錄的是每個素因子的個數
        while(n%i==0)
        {
            n/=i;
            a++;
        }
        s=s*(a+1);
    }
    if(n>1)
        s=s*2;
    return s;
}
 
int main(){
    for(int i = 1; i < maxn; i++) {
        for(int j = i; j < maxn; j += i)
            num[j]++;
    }//一種求因子的方法 
    
    int T, a, b; 
	scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &a, &b);
        int t = __gcd(a, b);
       
        printf("%lld\n", 1ll * count(a) * count(b) - 1ll*(count(t) - 1) * count(t) / 2);
    }
    return 0;
}
           

連結:https://www.nowcoder.com/acm/contest/185/B

來源:牛客網

題目描述

給出一個 n * n 的鄰接矩陣A.

A是一個01矩陣 .

A[i][j]=1表示i号點和j号點之間有長度為1的邊直接相連.

求出從 1 号點 到 n 号點長度為k的路徑的數目.

輸入描述:

第1行兩個數n,k (20 ≤n ≤ 30,1 ≤ k ≤ 10)

第2行至第n+1行,為一個鄰接矩陣

輸出描述:

題目中所求的數目

離散數學題,矩陣自乘k次就能知道幾号點到幾号點的長度為k的路徑有幾條

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#define MA 50  
typedef long long ll; 
ll G[MA][MA], mu[MA][MA], g[MA][MA];  
int main(){
  
    int n, m;  
    int i, j, k;  
    ll num;  
    scanf("%d%d",&n,&m);
    for(i=0; i<n; i++){  
        for(j=0; j<n; j++){  
            scanf("%lld", &G[i][j]);  
            g[i][j] = G[i][j];  
        }  
    }  
    while(--m){  
    
        memset( mu, 0, sizeof(mu));  
        for(i=0; i<n; i++){  
            for(j=0; j<n; j++){  
                for(k=0; k<n; k++){  
                    mu[i][j] += g[i][k] * G[k][j];  
                }  
            }  
        }  
        for(i=0; i<n; i++){  
            for(j=0; j<n; j++){  
                G[i][j] = mu[i][j];  
            }  
        }  
    }  
    num = 0;  
    num=G[0][n-1];
    
    printf("%lld\n",num);  
    
    return 0;  
} 
           

連結:https://www.nowcoder.com/acm/contest/185/C

來源:牛客網

題目描述

給出一個數列 A,求出一個數列B.

其中Bi 表示 數列A中 Ai 右邊第一個比 Ai 大的數的下标(從1開始計數),沒有找到這一個下标 Bi 就為0

輸出數列B

輸入描述:

第一行1個數字 n (n ≤ 10000)

第二行n個數字第 i 個數字為 Ai (0 ≤ Ai ≤ 1000000000)

輸出描述:

一共一行,第 i 個數和第 i+1 個數中間用空格隔開.

暴力

#include<iostream>
#include<cstdio>
using namespace std;
const int N=10000+100;
int a[N]; 
int b[N];

int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&a[i]);
		
	}
	int num;
    for(int i=0;i<n;i++){
    	for(int j=i+1;j<n;j++){
    		if(a[j]>a[i]){
    			b[i]=j+1;
    			break;
			} 
		}
	}
	for(int i=0;i<n;i++){
		if(i!=n-1){
			printf("%d ",b[i]);
		}
		else{
			printf("%d",b[i]);
		}
		
	}
	
}
           

連結:https://www.nowcoder.com/acm/contest/185/D

來源:牛客網

題目描述

Johnson和Nancy要在星光下吃晚餐。這是一件很浪漫的事情。

為了增加星光晚餐那浪漫的氛圍,他拿出了一個神奇的魔法棒,并且可以按照一定的規則,改變天上星星的亮暗。

Johnson想考考Nancy,在他揮動魔法棒後,會有多少顆星星依舊閃耀在天空。他知道,Nancy一定會一口說出答案。

Nancy當然知道怎麼做啦,但她想考考你!

Johnson先将天上n個星星排成一排,起初它們都是暗的。

他告訴他的妹子,他将揮動n次魔法棒,第i次揮動會将編号為i的正整數倍的星星的亮暗反轉,即亮的星星轉暗,暗的星星轉亮。

Johnson想問Nancy,最終會有多少個星星依舊閃亮在天空。

輸入描述:

一個整數n,含義請見題目描述。

輸出描述:

一個整數ans,即n次操作後會有多少個星星依舊閃亮。

這個題知道真相的我眼淚掉下來,因為隻有因子個數為奇數的才亮,然後隻有完全平方數有奇數個因子,推導詳見:傳送門

#include<cstdio>
#include<cmath>
long long n;
int main()
{
    scanf("%lld",&n);
    printf("%lld",(long long)(sqrt(n)));
}
           

連結:https://www.nowcoder.com/acm/contest/185/E

來源:牛客網

題目描述

給定括号長度N,給出一串括号(隻包含小括号),計算出最少的交換(兩兩交換)次數,使整個括号序列比對。

我們認為一個括号比對,即對任意一個’)’,在其左側都有一個’('與它比對,且他們形成一一映射關系。

輸入描述:

第一行:整數N,表示括号序列長度

第二行:一個字元串,表示括号

輸出描述:

一個整數,表示最少的交換次數

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e6 + 10;
char s[N];
int n;
 
int main() {
    scanf("%d%s", &n, s + 1);
    int cnt = 0;
    for(int i = 1 ; i <= n ; ++ i) {
        if(s[i] == '(') ++ cnt;
        else {
            if(cnt) -- cnt;
            
        }
    }
    
    printf("%d\n", (cnt+1)/ 2 );
}
           

連結:https://www.nowcoder.com/acm/contest/185/F

來源:牛客網

題目描述

輸入一個整數X,求一個整數N,使得N!恰好大于XX。

輸入描述:

第一行:一個整數X

輸出描述:

第一行:一個整數N

備注:

每個測試點所對應的X滿足:

第i個測試點輸入的值為第i-1個測試點輸入的值乘以10再加上7。

特别的,第一個測試點所輸入的值為7。

提示:資料共有10組。

我就是斯特林公式打表,然後可能寫錯了,打表失敗,算了直接貼大佬的二分算了

#include<bits/stdc++.h>
typedef long long ll;
 
using namespace std;
const double pi = acos(-1), e = exp(1.0);
ll x;
double up;
bool check(double n){
    return 0.5 * log(2 * pi * n) + n * log(n / e) >= up;
}
int main() {
    scanf("%lld",&x);
    up = x * log(x);
    int times = 51;
    double l = 1, r = 1e13, ans;
    while(times--) {
        ll mid = (l + r) / 2;
        if(check(mid)) ans = mid, r = mid;
        else l = mid;
    }
    cout <<(long long )ans;
    return 0;
}
           
#include <iostream>
#include <cstdio>
#include <cmath>
  
using namespace std;
  
int main()
{
    long long x;
      
    cin>>x;
      
    long long l=x,r=x*3,mid;
     
    while (l<r)
    {
        mid=(l+r)/2;
        if (log(mid*1.0)*mid-mid+log(x)-1<x*log(x))
        {
            l=mid+1;
        }
        else
        {
            r=mid;
        }
    }
     
    cout<<l;
      
    return 0;
}