10月25日比赛

T1

找规律,感觉很恶心,实际上不难(因为大样例错了?)

总的就是往外围六边型,然后就可以发现一些规律。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll k[1000077];
int main() {
    int n,ans = 0,tot = 1;
    cin>>n;
    for(int i = 1;i <= 20000;++ i) {
        k[++tot] = ((((i+i)*(i+i+1)/2)-((i)*(i+1)/2))*2+i+i+1);
    }
    ll pos = lower_bound(k+1,k+tot+1,n)-k;
    cout<<pos*6;
	return 0;
}

T2

题目好难懂,写的时候费劲。

真心没有把这个联系到图论上,问zbq学长,他的回答是:“怎么想到图论的就跟怎么想到正解的一个样”。

然后赛时打的暴力,不过思路错啦,赛后改过来了。

#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
int read() {
    int x = 0,f = 1; char c = getchar();
    while(c < '0'||c > '9') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    return x*f;
}
struct op{
    int f,c,d,a;
}v[1000077],g[1000077];
int n,nm[1000077];
ll ans;
void dfs(int k) {
    if(k==n+1) {
        for(int i = 1;i <= n;++ i) v[i] = g[i];
        ll res = 0;
        for(int i = 1;i <= n;++ i) {
            if(nm[i]) {
                res += 1ll*v[v[i].f].a*(v[v[i].f].d-v[i].c);
                v[v[i].f].a = 0;
            }
        }
        ans = max(ans,res); 
        return ;
    }
    for(int i = 0;i <= 1;++ i) {
        nm[k] = i;
        dfs(k+1);
    }
}
signed main() {
//    freopen("dundundun.in","r",stdin); 
//    freopen("dundundun.out","w",stdout); 
    cin>>n;
    int bj1 = 1,bj2=1,bj3=1;
    for(int i = 1;i <= n;++ i) {
        v[i].f=read();v[i].c=read();v[i].d=read();v[i].a=read();
        g[i] = v[i];
        if(v[i].f!=i) bj1=0;
        if(v[i].a!=1) bj3=0;
    }
    if(bj1) {
        for(int i = 1;i <= n;++ i) {
            if(v[i].d-v[i].c > 0) ans += 1ll*(v[i].d-v[i].c)*v[i].a;
        }
        cout<<ans;
        return 0;
    }
    if(bj3) {
        dfs(1);
        cout<<ans;
        return 0;
    }
    dfs(1);
    cout<<ans;
	return 0;
}


T3

并不会正解,zbq学长也说了,这个属于最难得一个题了,所以就打了暴力,按理来说这个暴力复杂度应该可以拿很多分,不过因为某些特殊的字符串导致答案会出现错误,于是就30分了。

#include<bits/stdc++.h>
using namespace std;
string s,g,h;
bool chck() {
    int k = h.find(g);
    while(k != -1) {
        h.erase(k,g.size());
        k = h.find(g);
    }
    return h=="";
}
int main() {
    int t;
    cin>>t;
    while(t--) {
        cin>>s;
        g = "";
        int bj = 0,n = s.size();
        for(int len = 0;len < n;++ len) {
            for(int i = 0;i+len < n;++ i) {
                int j = i+len;
                g = s.substr(i,len+1);
                h = s;
                h.erase(i,len+1);
                if(chck()) {
                    bj = 1;
                    cout<<g<<'\n';
                    break;
                }
            }
            if(bj) break;
        }
    }
	return 0;
}

T4

很容易就想到了n3的做法,不过刚开始题目比较难理解,n3有60分,我很高兴的写完了,一
遍过了大样例,但很可惜大样例太弱了,枚举的地方错了没看出来,于是就挂成15了。

#include<bits/stdc++.h>
#include <endian.h>
#define ll long long
using namespace std;
int read() {
    int x = 0,f = 1; char c = getchar();
    while(c < '0'||c > '9') {if(c=='-')f=-1;c = getchar();}
    while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c = getchar();}
    return x*f;
}
struct op{
    int to,nxt,ds;
}e[1000001];
int head[1000001],num;
void add(int frm,int to,int ds) {
    e[++num] = op{to,head[frm],ds};
    head[frm] = num;
}
int n,a,m,C;
struct opp{
    int diss;
    int wz;
    bool operator <(const opp&jk) const {
        return jk.diss<diss;
    }
};
int ds[100001],uot[100001],f[1007][1007],h[1007][1007];
bool vis[100001]; 
priority_queue<opp>q;
void dij(int s) {
    memset(ds,0x3f,sizeof ds);
    q.push(opp{0,s}); ds[s] = 0;
    while(!q.empty()) {
        int x = q.top().wz; q.pop();
        if(vis[x]) continue; vis[x] = 1;
        for(int i = head[x];i;i = e[i].nxt) {
            int v = e[i].to;
            if(ds[v] > ds[x]+e[i].ds) {
                ds[v] = ds[x]+e[i].ds;
                q.push(opp{ds[v],v});
            }
        }
    }
}
ll ans=1e18;
int main() {
    cin>>n>>m>>C;
    for(int i = 1;i <= m;++ i) {
        int u=read(),v=read(),w=read();
        add(u,v,w);
        add(v,u,w);
        f[u][v] = f[v][u] = w;
        h[u][v] = h[v][u] = w;
    }
    dij(1);
    int mx = -1;
    for(int i = 1;i <= n;++ i) mx = max(mx,ds[i]);
    for(int lim = 1;lim <= mx;++ lim) {
        int top = 0;
        for(int i = 1;i <= n;++ i) if(ds[i] <= lim) uot[++top] = i;
        ll res = 0;
        for(int i = 1;i <= top;++ i) {
            for(int j = 1;j <= top;++ j) {
                f[uot[i]][uot[j]] = 0;
            }
        }
        for(int i = 1;i <= n;++ i) {
            for(int j = 1;j <= n;++ j) {
                res += f[i][j];
                f[i][j] = h[i][j];
            }
        }
        ans = min(ans,(res>>1)+C*lim);
    }
    cout<<ans;
	return 0;
}
posted @ 2022-10-25 22:48  双枫  阅读(9)  评论(1编辑  收藏  举报