2021.6.9模拟赛

考试题传送门

我靠为啥考场一个不会,下来做觉得除了 T1 水的一批啊

T4被 \(Hack\) 没资格说水/lb

T1

实 在 不 会 /kk

观摩一下 @Blueqwq 彁彁の Random 吧

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=10010;
const int M=400000;
inline int read(){
	int x=0;bool f=false;char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-')	f=true;
		ch=getchar();
	}
	while(isdigit(ch)){
		x=(x<<3)+(x<<1)+(ch^48);
		ch=getchar();
	}
	return f?-x:x;
}
int n,m;
int mon[N];
int total;
int w[M];
int s[M];
int randmax,randmin;
void prerand(){
	sort(w+1,w+m+1);
	sort(mon+1,mon+n+1);
	for(int i=1;i<=m;i++)
		s[i]=s[i-1]+w[i];
	for(int i=1;i<=n;i++)
		total+=mon[i];
	for(int i=m;i;i--)
		if(s[i]<total){
			randmax=i;
			break;
		}
	int i=1,j=1;
	while(i<=n&&j<=m){
		if(mon[i]<w[j]){
			i++;
		}else{
			mon[i]-=w[j];
			j++;
		}
	}
	randmin=j-1;
}
signed main(){
	srand(time(0));
	n=read();
	for(int i=1;i<=n;i++)
		mon[i]=read();
	m=read();
	for(int i=1;i<=m;i++)
		w[i]=read();
	prerand();
	printf("%lld\n",randmin+(rand()*rand()%(randmax-randmin+1)));
	return 0;
}

T2

这题是不是比国王游戏简单啊

整体思路也是等价换人

不能啊,我操,考试结束前没码完的暴力竟然也能过!?真就玩我心态呢?

#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
#include<chrono>
#include<random>
#include<unordered_map>
using namespace std;

#define ll long long
#define ull unsigned long long
#define rll register long long
#define ri register int
//#define int long long

const int N=100010;
int n;
int ans=-0x7fffffff;
int wt=0;
struct kyon{
    int w,s,ws,num;
}r[N];

inline ll read(){
    ll x=0,y=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
            y=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*y;
}

inline bool cmp(kyon x,kyon y) {
	return x.ws>y.ws;
}

signed main(){
    n=read();
    for(ri i=1;i<=n;i++){
        r[i].w=read(),r[i].s=read();
        r[i].ws=r[i].w+r[i].s;
        wt+=r[i].w;
    }
    sort(r+1,r+n+1,cmp);
    for(ri i=1;i<=n;i++){
        wt-=r[i].w;
        ans=max(ans,wt-r[i].s);
    }
    printf("%d",ans);
    return 0;
}

T3

(其实在百度搜“ufo有一片矩形的土地”即可)

考场唯一做出来的题/kk

正解是二分,找到符合要求的就左侧 +1 ,否则就右侧 -1 。

还 T 了!二分还能 T 绝了

考场 \(Code(50pts)\)

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define ull unsigned long long
#define rll register long long
#define ri register int
//#define int long long

const int N=1010;
const int dx[4]={0,-1,0,1};
const int dy[4]={1,0,-1,0};
int n,m;
int mx,my,ansx,ansy;
int q=0,qx,qy;
ll val=-1;
ll d[N][N];
int f[N][N];
int mem[N];

inline ll read(){
    ll x=0,y=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
            y=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*y;
}

inline bool work(ll x){
    memset(f,0,sizeof(f));
    int mid;
    for(ri i=1;i<=n;i++){
        mid=0;
        for(ri j=1;j<=m;j++)
            if(d[i][j]>=x)
                mem[mid++]=j;
        for(ri j=0;j<mid;j++){
            for(ri k=j+1;k<mid;k++){
                if(f[mem[j]][mem[k]]!=0)
                    return 1;
                else
                    f[mem[j]][mem[k]]=1;
            }
        }
    }
    return 0;
} 

inline void bfs(){
    while(1){
        if(q>val)
            break;
        ll mid=(q+val)>>1;
        if(work(mid)!=0)
            q=mid+1;
        else
            val=mid-1;
    }
    printf("%lld",val);
}

signed main(){
    n=read(),m=read();
    if(n<2||m<2){
        printf("0");
        return 0;
    }
    for(ri i=1;i<=n;i++){
        for(ri j=1;j<=m;j++){
            d[i][j]=read();
            val=max(val,d[i][j]);
            if(val==d[i][j])
                mx=i,my=j;
        }
    }
    bfs();
    return 0;
}

实际上,从小的方向扫时,不能从 \(0\) 开始,这会导致最后一个点 T 掉,进而整个 \(Subtask\) 没分 \(qwq\)

应该从最小值开始扫

\(100pts\)

#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
#include<chrono>
#include<random>
#include<unordered_map>
using namespace std;

#define ll long long
#define ull unsigned long long
#define rll register long long
#define ri register int
//#define int long long

const int N=1010;
const int dx[4]={0,-1,0,1};
const int dy[4]={1,0,-1,0};
int n,m;
int mx,my,ansx,ansy;
ll val=-1,dval=0x7fffffff;
ll d[N][N];
int f[N][N];
int mem[N];

inline ll read(){
    ll x=0,y=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
            y=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*y;
}

inline bool work(ll x){
    memset(f,0,sizeof(f));
    int mid;
    for(ri i=1;i<=n;i++){
        mid=0;
        for(ri j=1;j<=m;j++)
            if(d[i][j]>=x)
                mem[mid++]=j;
        for(ri j=0;j<mid;j++){
            for(ri k=j+1;k<mid;k++){
                if(f[mem[j]][mem[k]])
                    return 1;
                else
                    f[mem[j]][mem[k]]=1;
            }
        }
    }
    return 0;
}

inline void bfs(){
    while(dval<=val){
        ll mid=(dval+val)>>1;
        if(work(mid))
            dval=mid+1;
        else
            val=mid-1;
    }
    printf("%lld",val);
}

signed main(){
    n=read(),m=read();
    if(n<2||m<2){
        printf("0");
        return 0;
    }
    for(ri i=1;i<=n;i++){
        for(ri j=1;j<=m;j++){
            d[i][j]=read();
            val=max(val,d[i][j]);
            dval=min(dval,d[i][j]);
        }
    }
    bfs();
    return 0;
}

T4

这个题目背景啊它就很 * Miracle *​

\(97pts\)

简简单单的搜索

先分每个 \(y\) 去搜,再分 \(x\) ,暴力枚举每一个的最大子矩阵和啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊我自己都不知道我在说什么啊啊啊啊啊啊啊啊啊啊啊啊

自己看看核心代码吧

for(ri i=y_1;i<=y2;i++){
    for(ri j=i;j<=y2;j++){
        int cnt=-1;
            for(ri k=x1;k<=x2;k++){
                if(cnt>=0)
                    cnt+=w[k][j]-w[k][i-1];
                else
                    cnt=w[k][j]-w[k][i-1];
                ans=max(ans,cnt);
            }
        }
    }
}

\(Code(97pts)\)

#include<algorithm>
#include<bitset>
#include<cctype>
#include<cerrno>
#include<clocale>
#include<cmath>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<limits>
#include<list>
#include<map>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<utility>
#include<vector>
#include<cwchar>
#include<cwctype>
#include<chrono>
#include<random>
#include<unordered_map>
using namespace std;

#define ll long long
#define ull unsigned long long
#define rll register long long
#define ri register int
//#define int long long

const int N=55;
int n,m,Q,ans;
int w[N][N];
int x1,y_1,x2,y2;

inline ll read(){
    ll x=0,y=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')
            y=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    return x*y;
}

inline void dfs(){
    for(ri i=y_1;i<=y2;i++){
        for(ri j=i;j<=y2;j++){
            int cnt=-1;
            for(ri k=x1;k<=x2;k++){
                if(cnt>=0)
                    cnt+=w[k][j]-w[k][i-1];
                else
                    cnt=w[k][j]-w[k][i-1];
                ans=max(ans,cnt);
            }
        }
    }
    printf("%d\n",ans);
}

signed main(){
    n=read(),m=read(),Q=read();
    for(ri i=1;i<=n;i++)
        for(ri j=1;j<=m;j++){
            w[i][j]=read();
            w[i][j]+=w[i][j-1];
        }
    while(Q--){
        x1=read(),y_1=read(),x2=read(),y2=read();
        ans=-1e4;
        dfs();
    }
    return 0;
}

昨天晚上 @AzusaCat 填了一组 \(Hack\) 数据,卡掉了上面的 \(O(n^3q)\) 暴力,所以会丢 \(3\)

@LawrenceSivan 给我讲了讲,感谢他的讲解/bq

az正解就先咕了罢我先睡会儿

posted @ 2021-07-14 20:07  BFNewdawn  阅读(29)  评论(0编辑  收藏  举报