“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛水题。

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数组即可得到答案。
完结。

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