1. 程式人生 > 其它 >2021-02-06周賽

2021-02-06周賽

技術標籤:總結演算法c++

文章目錄


前言

2-6號周賽


一、幼兒數學

給你一個只包含數字[0,9]的字串。
你可以在字元之間加上' + '或' - ',使得字串成為一個帶加減法的式子。
例如對於“12345”,你可以將他變成"123+4-5”。
現在給你一個整數N,計算有多少種方法可以使式子的結果等於N。
你只能在兩個相鄰字元中選擇最多一個符號。

Input

多組資料,每組資料給出數字串S和一個整數n,( |S|<=12,|n|<1e12)

Output

輸出有多少種方法,可以使式子的結果等於N

Sample Input

123456789 3
21 1
Sample Output
18
1

從最後一個數字開始往前面搜尋,每一個數字都會有三種可能處理的情況,就是加上“+”,或者加上“-”,或者不處理,這樣子的dfs下去。

#include <iostream>
#include<cstdio>
#include<string.h>
#define ll long long

using namespace std;

char s[100];//這樣子可以將每個數字分開
ll n;
int len,ans;
void dfs(ll sum,ll num,int pos,int op)
{
    if(pos==len)
        {
            if(n==sum+num*op)
            ans++;
            return;
        }

    dfs(sum,num*10+s[pos]-'0',pos+1,op);//就是不處理
    dfs(sum+num*op,s[pos]-'0',pos+1,1);//執行加法
    dfs(sum+num*op,s[pos]-'0',pos+1,-1);//執行減法


}


int main()
{
  while(cin>>s>>n)
  {
      ans=0;
      len=strlen(s);
      dfs(0,s[0]-'0',1,1);//如果一直不處理,那麼最後就sum+num,所以這裡的op一開始就只能是1
      cout<<ans<<endl;

  }
    return 0;
}



二、清空快取區

在寫第二題的時候,我想偷個懶,懶得開陣列,只讀取第一個字元,然後再清除快取區,首先想到的是getchar()來清除快取區,但是好像並沒有起作用,跟沒有加得效果是一樣的,但是我再加了一個getchar()就起作用了,很有可能是回車在作怪,讓下一個讀取讀入了,從而導致讀取錯誤,回車就直接讓第二個結果與第一個一樣並沒有真正執行,%c是可以讀取回車,該怎麼改進,及其相關問題,故該問題有待再進一步修煉解決

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<queue>
#include<cmath>

using namespace std;

double check(char b)
{
    double ans=1;
    double tans=1000/1024.0;
    switch(b)
    {
    case 'Y':ans*=tans;
    case 'Z':ans*=tans;
    case 'E':ans*=tans;
    case 'P':ans*=tans;
    case 'T':ans*=tans;
    case 'G':ans*=tans;
    case 'M':ans*=tans;
    case 'K':ans*=tans;
    case 'B':break;
    default:break;
    }

    return ans;
}
int main()
{
    int n,x=1;

    scanf("%d",&n);
    while(n--)
    {
        int a;
         double ans=0;
        char b;
        scanf(" %d[%c]",&a,&b);
        getchar();
        getchar();
       ans=1-check(b);
    printf("Case #%d: %0.2lf%%\n",x,ans*100);
    x++;
    }
    return 0;
}

關於getchar()

getchar()是在輸入緩衝區順序讀入一個字元(包括空格、回車和Tab)
getchar()使用不方便,解決方法:
(1)使用下面的語句清除回車:
while(getchar()!='\n');
(2)用getche()或getch()代替getchar(),其作用是從鍵盤讀入一個字元(不用按回車),注意要包含標頭檔案<conio.h>

由於getchar()不太靠譜,所以我用了fflush函式,但可能這個騷操作並沒有通過做題的編譯器,竟然讀不出來,沒過,自己的編譯器都過了,只好,老老實實開陣列,早知道一開始不偷懶了,繞了這麼大一圈子

fflush()函式

標頭檔案:#include<stdio.h>

作用:更新快取區

fflush(stdin):重新整理緩衝區,將緩衝區內的資料清空並丟棄
fflush(stdout):重新整理緩衝區,將緩衝區內的資料輸出到裝置

三、最大公約數和最小公倍數

最大公約數:運用輾轉相除法

最小公倍數:兩數乘積/最大公約數

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<queue>
#include<cmath>

int main()
{
	int a,b,temp;
	int m,n;
	printf("input two numbers:\n");
	scanf("%d,%d", &m, &n);
	a =max(m,n);
	b= min(m,n);
	while (a%b != 0)
	{
		temp = a%b;
		a = b;
		b = temp;
	 }
	printf("最大公約數為:%d\n", b);
	printf("最小公倍數為:%d",m*n/b);
	return 0;
}

求最大公約數gcd還有幾種不同的寫法嘞

while(a、b不可以為0)

while (a%b != 0)
	{
		temp = a%b;
		a = b;
		b = temp;
	 }//b是最大公約數

三目運算(a、b可以為0)

int gcd(int a,int b) {
    return b>0 ? gcd(b,a%b):a;
}

位運算(a、b可以為0)

int gcd(int a,int b) {
    while(b^=a^=b^=a%=b);
    return a;
}

gcd庫函式(a、b可以為0)

#include <algorithm>
int gcd(int a,int b) {
	return __gcd(a,b);
}

四、小技巧

1、要巧用二分來求,可以減少很多,也不用自己想著如何剪枝剪枝。

2、計算機當中的一些表示

long long型別的輸出是%lld

int a = -1;  // 宣告一個有符號整數
printf("%u\n", a); // 無符號整數的形式
printf("%d\n", a); // 有符號整數的形式

3、求各位數之和--遞迴寫法

int f(int p){
	return (p==0)?0:(p%10+f(p/10));

4.switch的那個case用字元一定要加''

5.對數的表達形式

res = logm(n)

五、進位制轉換

眾所周知,字元'a'的ASCII碼是97。
現在,求一組給定的數字中有多少個字母a。
請注意,這裡的數字是由計算機中的32位整數給出的。
也就是說,1位代表4個字元(一個字元由8位二進位制數字表示)。

Input

多組輸入,每組輸入第一行是n,表示有n個整數,接下來給出n個數a(i)。
(n<=100,1<=a(i)<2^32)

Output

輸出有多少個字元a

Sample Input

3
97 24929 100

Sample Output

3

這個題我連題目都沒看懂,

其實這裡的迴圈因為32位的給出來的,分給了8位二進位制,所以,最多也就是迴圈4次,也可用for代替那個while

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<cstdio>
#include<queue>
#include<cmath>

using namespace std;
signed main()
{
    int n;
    while(cin>>n)
    {
        int ans=0;
        while(n--)
        {
            int x;
            cin>>x;
            while(x)
            {
                if(x%256==97)
                {
                    ans++;
                }
                x/=256;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

signed main()

就是為了區分#define int long long ,所以就是很雞肋,emmm,沒太懂反正就大概知道是等同於int main()

六、數學推導

#include <bitsdc++.h>
#define IOF ios_base::sync_with_stdio(0)
#define ll long long
using namespace std;

int main(){
    int t, r; ll n;
    double x;
    IOF;
    cin >> t;
    while (t--){
        cin >> n;
        x = n * log10((double)n) - (ll)(n * log10((double)n));
        r = (int)(pow(10.0, x));
        cout << r << endl;
    }
}

 

long long fastPower(long long base, long long power) {
    long long result = 1;
    while (power > 0) {
        if (power & 1) {//此處等價於if(power%2==1),但是他的效率會更高一些
            result = result * base ;
        }
        power >>= 1;//此處等價於power=power/2,但是他的效率會更高一些
        base = base * base;
    }
    return result;
}