“科林明倫杯”哈爾濱理工大學第十屆程序設計競賽水題。

Powered by:AB_IN 局外人
只AC了一個題。。
很多題雖然結果對,但是犯了沒加換行,或者沒清0,之類的錯誤。
得好好反思下自己了,太依賴py。

B 減成一

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll maxn=1e7+10;
char buf[1 << 21], *p1=buf, *p2=buf;
inline ll getc(){
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline ll read() {
    ll ret = 0,f = 0;char ch = getc();
    while (!isdigit (ch)) {
        if (ch == '-') f = 1;
        ch = getc();
    }
    while (isdigit (ch)) {
        ret = ret * 10 + ch - 48;
        ch = getc();
    }
    return f ? -ret : ret;
}
inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';     tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
ll t,n,a[maxn],b[maxn],ans,cnt;
int main()
{
    t=read();
    while(t--){
        cnt=0;
        n=read();
        for(int i=1;i<=n;i++){
            a[i]=read();
            b[i]=a[i]-a[i-1];
            if(b[i]>0) cnt+=b[i];
        }
        write(cnt-1);putchar(10);
    }
}

很高興能在賽後拿下B題耗時最少。
在這裏插入圖片描述
很簡單的差分,和海港一題類似,相當於全變成一樣的之後,全部減成1。
這題沒對是因爲背錯了asc碼,32是空格,10是換行。

C 面積

n=int(input())
while n>0:
    n-=1
    d=int(input())
    s=d**2+((d**2)*3.14/2)
    print("%.2f"%s)

兩個事情。
1.因爲省事用的py,如果沒什麼大數,儘量用c++。
2.python 3 print(f'{s:.2f})'不能這麼寫!會有不知名的錯誤。
pypy3可以(因爲是3.6.1版本)平常也可以。

#include<iostream>
using namespace std;
int main()
{
    int t;
    double n;
    double pi = 3.14;
    cin>>t;
    while(t--){
        double r;
        cin>>n;
        r = n/2;
        printf("%.2lf\n",2*r*r*pi+n*n);
    }
    return 0;
}

E 賽馬

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll maxn=1e3+10;
char buf[1 << 21], *p1=buf, *p2=buf;
inline ll getc(){
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline ll read() {
    ll ret = 0,f = 0;char ch = getc();
    while (!isdigit (ch)) {
        if (ch == '-') f = 1;
        ch = getc();
    }
    while (isdigit (ch)) {
        ret = ret * 10 + ch - 48;
        ch = getc();
    }
    return f ? -ret : ret;
}
inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';     tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
ll t,n,a[maxn],b[maxn],ans,cnt;
int main()
{
    t=read();
    while(t--){
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        cnt=0;
        n=read();
        for(int i=1;i<=n;i++){
            a[i]=read();
        }
        for(int i=1;i<=n;i++){
            b[i]=read();
        }
        sort(a+1,a+1+n);
        sort(b+1,b+1+n);
        for(int i=1;i<=n;i++){
            ans=upper_bound(a+1,a+n+1,b[i])-a;
            if(ans<=n)
            b[i]=0x3f3f3f3f,a[ans]=-0x3f3f3f3f,cnt++;
        }
        write(cnt),putchar(10);
    }
}

比賽時這題wa是因爲cnt沒清0。賽後跑了4ms。
和別人的思路不太一樣。
我是用的二分,在a裏找返回比b[i]大的數的下標ans。要是找到了,a[ans]變成最小 b[i]變成最大cnt++ 這樣相當於刪除了這倆數據。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll maxn=1e3+10;
char buf[1 << 21], *p1=buf, *p2=buf;
inline ll getc(){
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline ll read() {
    ll ret = 0,f = 0;char ch = getc();
    while (!isdigit (ch)) {
        if (ch == '-') f = 1;
        ch = getc();
    }
    while (isdigit (ch)) {
        ret = ret * 10 + ch - 48;
        ch = getc();
    }
    return f ? -ret : ret;
}
inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';     tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
ll t,n,a[maxn],b[maxn],ans;
int main()
{
    t=read();
    while(t--){
        ans=0;
        n=read();
        for(int i=1;i<=n;i++){
            a[i]=read();
        }
        for(int i=1;i<=n;i++){
            b[i]=read();
        }
        sort(a+1,a+1+n);
        sort(b+1,b+1+n);
        int la=1,lb=1;
        while(la<=n&&lb<=n)
        {
            if(a[la]>b[lb]){
                la++;
                lb++;
                ans++;
            }
            else la++;
        }
        write(ans),putchar(10);
    }
}

中規中矩的類似尺取,成立了就都移,不成立只移自己的馬。跑了3ms。

F 三角形

#include<bits/stdc++.h>
#pragma GCC optimize(2)
typedef unsigned long long ll;
using namespace std;
const ll maxn=1e3+10;
ll f[maxn],a,t,cnt;
char buf[1 << 21], *p1=buf, *p2=buf;
inline ll getc(){
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline ll read() {
    ll ret = 0,f = 0;char ch = getc();
    while (!isdigit (ch)) {
        if (ch == '-') f = 1;
        ch = getc();
    }
    while (isdigit (ch)) {
        ret = ret * 10 + ch - 48;
        ch = getc();
    }
    return f ? -ret : ret;
}
inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0;    while (tmp > 0) { F[cnt++] = tmp % 10 + '0';     tmp /= 10; }    while (cnt > 0)putchar(F[--cnt]); }
void init(){
    f[1]=1;
    f[2]=1;
    for(int i=3;i<=93;i++){
        f[i]=f[i-1]+f[i-2];
    }
}
int main(){
    init();
    t=read();
    while(t--){
        cnt=0;
        a=read();
        for(int i=1;i<=93;i++){
            if(a>=f[i]) a-=f[i],cnt++;
            else break;
        }
        write(cnt),putchar(10);
    }
}

三角形兩邊之和大於第三邊,因此不構成 三角形的條件就是存在兩邊之和不超過另 一邊。所以按照斐波那契數列的方法切割 可以使得切割的段數最大。
數值很大,又沒負數,故開unsigned long long
根據py試出來,unsigned long long斐波那契數列最多到93位。

H 直線

t=int(input())
while t>0:
    t-=1
    n=int(input())
    print(n*(n-1)//2)

最讓我惱火的題。
因爲都是c++的題,/如果沒有特殊要求都改//
正規的要弄大數乘法。

大佬的模板。

下面是引用

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 10000, BASE = 1000000000, WIDTH = 9; //壓位
char in[10005];
struct bigint
{
    ll element[maxn]; //用來存放每一位(元)
    ll len;
    bigint operator=(ll num) //從ll向bigint轉換
    {
        memset(element, 0, sizeof(element));
        len = 0;
        while (num > 0)
        {
            element[len++] = num % BASE;
            num /= BASE;
        }
        return *this;
    }
    bigint operator=(const char *str) //從str向bigint轉換
    {
        memset(element, 0, sizeof(element));
        ll num_len = strlen(str);
        len = (num_len + WIDTH - 1) / WIDTH;
        int pos = 0;
        for (int i = num_len - 1; pos < len; i -= WIDTH)
        {
            for (int j = 0; j < WIDTH; j++)
            {
                element[pos] += (str[i - j] - '0') * pow(10, j);
                if (i - j == 0)
                {
                    break;
                }
            }
            pos++;
        }
        return *this;
    }
    bool operator<(const bigint &b) const //bigint小於比較
    {
        if (b.len != len)
        {
            return len < b.len;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return element[i] < b.element[i];
            }
        }
        return false;
    }
    bool operator<=(const bigint &b) const //bigint小於等於比較
    {
        if (b.len != len)
        {
            return len < b.len;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return element[i] < b.element[i];
            }
        }
        return true;
    }
    bool operator>(const bigint &b) const //bigint大於比較
    {
        if (b.len != len)
        {
            return len > b.len;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return element[i] > b.element[i];
            }
        }
        return false;
    }
    bool operator>=(const bigint &b) const //bigint大於等於比較
    {
        if (b.len != len)
        {
            return len > b.len;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return element[i] > b.element[i];
            }
        }
        return true;
    }
    bool operator==(const bigint &b) const //bigint等於比較
    {
        if (b.len != len)
        {
            return false;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return false;
            }
        }
        return true;
    }
    bigint operator+(const bigint &b) const //bigint加法
    {
        bigint ans;
        memset(ans.element, 0, sizeof(ans.element));
        ans.len = len;
        for (int i = 0; i < len; i++)
        {
            ans.element[i] += element[i] + b.element[i]; //加
            if (ans.element[i] >= BASE)                  //如果多了就借位
            {
                ans.element[i + 1] += ans.element[i] / BASE;
                ans.element[i] %= BASE;
            }
        }
        ans.len++;
        while (ans.element[ans.len - 1] == 0 && ans.len > 0) //清除空白高位
        {
            ans.len--;
        }
        return ans;
    }
    bigint operator-(const bigint &b) const //bigint減法
    {
        bigint ans;
        memset(ans.element, 0, sizeof(ans.element));
        ans.len = len;
        for (int i = 0; i < len; i++)
        {
            ans.element[i] += element[i] - b.element[i]; //減
            if (ans.element[i] < 0)                      //如果多了就借位
            {
                ans.element[i] += BASE;
                ans.element[i + 1]--;
            }
        }
        while (ans.element[ans.len - 1] == 0 && ans.len > 0) //清除空白高位
        {
            ans.len--;
        }
        return ans;
    }
    bigint operator*(const bigint &b) const //bigint乘法
    {
        bigint ans;
        memset(ans.element, 0, sizeof(ans.element));
        ans.len = 2 * len;
        for (int i = 0; i < len; i++)
        {
            for (int j = 0; j < b.len; j++)
            {
                ans.element[i + j] += element[i] * b.element[j]; //乘
                if (ans.element[i + j] >= BASE)                  //如果多了就借位
                {
                    ans.element[i + j + 1] += ans.element[i + j] / BASE;
                    int cur = i + j + 1;
                    while (ans.element[cur] >= BASE)
                    {
                        ans.element[cur + 1] += ans.element[cur] / BASE;
                        ans.element[cur] %= BASE;
                        cur++;
                    }
                    ans.element[i + j] %= BASE;
                }
            }
        }
        ans.len++;
        while (ans.element[ans.len - 1] == 0 && ans.len > 0) //清除空白高位
        {
            ans.len--;
        }
        return ans;
    }
    bigint operator/(const ll &b) const //bigint除法 element len/b(先擼個半成品,這玩意兒太鬼畜了)
    {
        bigint ans;
        memset(ans.element, 0, sizeof(ans.element));
        ans.len = len;
        ans.element[len - 1] = (element[len - 1]) / b;
        ll lef = element[len - 1] % b;
        for (int i = len - 2; i >= 0; i--)
        {
            ans.element[i] = (element[i] + lef * BASE) / b;
            lef = (element[i] + lef * BASE) % b;
        }
        ans.len++;
        while (ans.element[ans.len - 1] == 0 && ans.len > 0) //清除空白高位
        {
            ans.len--;
        }
        return ans;
    }
    void bigint_init()
    {
        memset(element, 0, sizeof(element));
        len = 0;
    }
    bool bigint_read()
    {
        memset(in, 0, sizeof(in));
        scanf("%s", in);
        // if (!(strlen(in) == 1 && in[0] == '0'))
        //     return false;
        *this = in;
        return true;
    }
    void bigint_print()
    {
        if (len == 0)
            printf("0");
        else
        {
            printf("%lld", element[len - 1]);
            for (int i = len - 2; i >= 0; i--)
            {
                printf("%09lld", element[i]);
            }
        } //注意輸出的時候除了第一位其他不夠位數都用0補齊(避免遺漏前綴0)
        printf("\n");
    }
};

所以代碼

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn = 10000, BASE = 1000000000, WIDTH = 9; //壓位
char in[10005];
struct bigint
{
    ll element[maxn]; //用來存放每一位(元)
    ll len;
    bigint operator=(ll num) //從ll向bigint轉換
    {
        memset(element, 0, sizeof(element));
        len = 0;
        while (num > 0)
        {
            element[len++] = num % BASE;
            num /= BASE;
        }
        return *this;
    }
    bigint operator=(const char *str) //從str向bigint轉換
    {
        memset(element, 0, sizeof(element));
        ll num_len = strlen(str);
        len = (num_len + WIDTH - 1) / WIDTH;
        int pos = 0;
        for (int i = num_len - 1; pos < len; i -= WIDTH)
        {
            for (int j = 0; j < WIDTH; j++)
            {
                element[pos] += (str[i - j] - '0') * pow(10, j);
                if (i - j == 0)
                {
                    break;
                }
            }
            pos++;
        }
        return *this;
    }
    bool operator<(const bigint &b) const //bigint小於比較
    {
        if (b.len != len)
        {
            return len < b.len;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return element[i] < b.element[i];
            }
        }
        return false;
    }
    bool operator<=(const bigint &b) const //bigint小於等於比較
    {
        if (b.len != len)
        {
            return len < b.len;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return element[i] < b.element[i];
            }
        }
        return true;
    }
    bool operator>(const bigint &b) const //bigint大於比較
    {
        if (b.len != len)
        {
            return len > b.len;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return element[i] > b.element[i];
            }
        }
        return false;
    }
    bool operator>=(const bigint &b) const //bigint大於等於比較
    {
        if (b.len != len)
        {
            return len > b.len;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return element[i] > b.element[i];
            }
        }
        return true;
    }
    bool operator==(const bigint &b) const //bigint等於比較
    {
        if (b.len != len)
        {
            return false;
        }
        for (int i = b.len - 1; i >= 0; i--)
        {
            if (b.element[i] != element[i])
            {
                return false;
            }
        }
        return true;
    }
    bigint operator+(const bigint &b) const //bigint加法
    {
        bigint ans;
        memset(ans.element, 0, sizeof(ans.element));
        ans.len = len;
        for (int i = 0; i < len; i++)
        {
            ans.element[i] += element[i] + b.element[i]; //加
            if (ans.element[i] >= BASE)                  //如果多了就借位
            {
                ans.element[i + 1] += ans.element[i] / BASE;
                ans.element[i] %= BASE;
            }
        }
        ans.len++;
        while (ans.element[ans.len - 1] == 0 && ans.len > 0) //清除空白高位
        {
            ans.len--;
        }
        return ans;
    }
    bigint operator-(const bigint &b) const //bigint減法
    {
        bigint ans;
        memset(ans.element, 0, sizeof(ans.element));
        ans.len = len;
        for (int i = 0; i < len; i++)
        {
            ans.element[i] += element[i] - b.element[i]; //減
            if (ans.element[i] < 0)                      //如果多了就借位
            {
                ans.element[i] += BASE;
                ans.element[i + 1]--;
            }
        }
        while (ans.element[ans.len - 1] == 0 && ans.len > 0) //清除空白高位
        {
            ans.len--;
        }
        return ans;
    }
    bigint operator*(const bigint &b) const //bigint乘法
    {
        bigint ans;
        memset(ans.element, 0, sizeof(ans.element));
        ans.len = 2 * len;
        for (int i = 0; i < len; i++)
        {
            for (int j = 0; j < b.len; j++)
            {
                ans.element[i + j] += element[i] * b.element[j]; //乘
                if (ans.element[i + j] >= BASE)                  //如果多了就借位
                {
                    ans.element[i + j + 1] += ans.element[i + j] / BASE;
                    int cur = i + j + 1;
                    while (ans.element[cur] >= BASE)
                    {
                        ans.element[cur + 1] += ans.element[cur] / BASE;
                        ans.element[cur] %= BASE;
                        cur++;
                    }
                    ans.element[i + j] %= BASE;
                }
            }
        }
        ans.len++;
        while (ans.element[ans.len - 1] == 0 && ans.len > 0) //清除空白高位
        {
            ans.len--;
        }
        return ans;
    }
    bigint operator/(const ll &b) const //bigint除法 element len/b(先擼個半成品,這玩意兒太鬼畜了)
    {
        bigint ans;
        memset(ans.element, 0, sizeof(ans.element));
        ans.len = len;
        ans.element[len - 1] = (element[len - 1]) / b;
        ll lef = element[len - 1] % b;
        for (int i = len - 2; i >= 0; i--)
        {
            ans.element[i] = (element[i] + lef * BASE) / b;
            lef = (element[i] + lef * BASE) % b;
        }
        ans.len++;
        while (ans.element[ans.len - 1] == 0 && ans.len > 0) //清除空白高位
        {
            ans.len--;
        }
        return ans;
    }
    void bigint_init()
    {
        memset(element, 0, sizeof(element));
        len = 0;
    }
    bool bigint_read()
    {
        memset(in, 0, sizeof(in));
        scanf("%s", in);
        // if (!(strlen(in) == 1 && in[0] == '0'))
        //     return false;
        *this = in;
        return true;
    }
    void bigint_print()
    {
        if (len == 0)
            printf("0");
        else
        {
            printf("%lld", element[len - 1]);
            for (int i = len - 2; i >= 0; i--)
            {
                printf("%09lld", element[i]);
            }
        } //注意輸出的時候除了第一位其他不夠位數都用0補齊(避免遺漏前綴0)
        printf("\n");
    }
};
int t;
int main()
{
    cin>>t;
    while(t--)
    {
        bigint n;  //定義結構體
        bigint b;  //定義結構體
        b.bigint_init(); //清0
        n.bigint_init(); //清0
        n.bigint_read(); //讀入n
        b=1;
        n=n*(n-b); //必須是結構體之間的運算
        n=n/2; //好像大佬除法的還沒弄好。。
        n.bigint_print(); //輸出n
    }
    return 0;
}

J 最大值

i = int(input())
while i>0:
    i-=1
    x = input()
    for j in range(1,len(x)+1):
        if x.find(x[0:j],1,len(x))==-1 or j==len(x):
            print(j-1)
            break

就是找前綴串,如果一直符合就不停,不符合了,就輸出長度-1。
這種思維應該培養一下。不是應該將每一個符合條件的都放進去賦值,而是將不符合條件的停住,往前一個找最大值。

記一下find函數:

str.find(str, beg=0, end=len(string))

str – 指定檢索的字符串
beg – 開始索引,默認爲0。
end – 結束索引,默認爲字符串的長度。

如果包含子字符串返回開始的索引值,否則返回-1。

c++正解是KMP算法。
Ac串其實是kmp中next數組的含義,所以求 出字符串的next數組即可得到答案。
完結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章