能力提升综合题单-模拟,前缀和差分 题解

A - 铺地毯

在luogu,享受coding的快乐

见到题以后,一道水题

直接模拟二位数组。。。

《真·ACcode》:

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

const int maxn=100001;

int p[10001][10001]={-1};
int n;
int a[maxn],b[maxn],g[maxn],k[maxn];
int x,y;

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i]>>b[i]>>g[i]>>k[i]; 
	}
	cin>>x>>y;
	for(int i=1;i<=n;i++){
		for(int j=a[i];j<=a[i]+g[i];i++){
			for(int l=b[i];l<=b[i]+k[i];l++){
				p[j][l]=i;
			}
		}
	}
	cout<<p[x][y];
	
	return 0;
} 

然而

AC记录

之前还有过Run Excellently

范围是 10^5...

后来

发现矩阵中大部分空间都被浪费掉了

另外一种方法是用四个数组来记录矩形的四个参数,再扫一遍数组,通过检查坐标 (x,y) 是否在Rect[i]矩形内,更新最上面的地毯。

ACcode:

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

const int MAXN=10005;
int a[MAXN], b[MAXN], g[MAXN], k[MAXN];

int main(){
    int n,x,y;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i]>>b[i]>>g[i]>>k[i];
    }
    cin>>x>>y;
    int ans=-1;
    for(int i=0;i<n;i++){
        if(x>=a[i]&&y>=b[i]&&x<=a[i]+g[i]&&y<=b[i]+k[i]){
            ans=i+1;
        }
    }
    
    cout<<ans;
    
    return 0;
}

B - 多项式输出

在洛谷,享受coding的快乐

转自:https://www.luogu.com.cn/blog/home/solution-p1067
特判:
1.系数为0?结束,否则继续;
2.是开头第一项?跳转至(4),否则继续;
3.系数为正?输出加号并继续,否则继续;
4.系数是±1?继续,否则跳转至6;
5.是常数项(只有数字没有字母)?继续,否则跳转至7;
6.输出系数并继续;
7.系数是-1?继续,否则跳转至10;
8.是常数项?跳转至10,否则继续;
9.输出负号并继续;
10.指数>1?继续,否则跳转至12;
11.输出"x^指数"并继续;
12.指数=1?输出"x"并结束,否则结束;
对每一项都按流程跑一遍就AC了

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

int n,a;

int main(){
    cin>>n;
    for(int i=n;i>=0;i--){
        cin>>a;
        if(a){    
            if(i!=n&&a>0)cout<<"+";    
            if(abs(a)>1||i==0)cout<<a;     
            if(a==-1&&i)cout<<"-";   
            if(i>1)cout<<"x^"<<i;  
            if(i==1)cout<<"x";     
        }
    }
   return 0;
}

C - 生活大爆炸版石头剪刀布

在洛谷,享受coding的快乐

没什么难的,水题

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

int n,na,nb,x,y,xa[201],xb[201],i,j,a,ans,bns;

int main(){
    cin>>n>>na>>nb;
    for(i=1;i<=na;i++){
        cin>>x;
        xa[i]=x;
    }
    for(j=1;j<=nb;j++){
        cin>>y;
        xb[j]=y;
    }
    ans=0;
    bns=0;
    i=0;
    j=0;
    for(a=1;a<=n;a++){
        i++;
        j++;
        if(i>na)i=1;
        if(j>nb)j=1;
        if(xa[i]==0&&xb[j]==1)bns++;
        if(xa[i]==0&&xb[j]==2)ans++;
        if(xa[i]==0&&xb[j]==3)ans++;
        if(xa[i]==0&&xb[j]==4)bns++;
        if(xa[i]==1&&xb[j]==0)ans++;
        if(xa[i]==1&&xb[j]==2)bns++;
        if(xa[i]==1&&xb[j]==3)ans++;
        if(xa[i]==1&&xb[j]==4)bns++;
        if(xa[i]==2&&xb[j]==0)bns++;
        if(xa[i]==2&&xb[j]==1)ans++;
        if(xa[i]==2&&xb[j]==3)bns++;
        if(xa[i]==2&&xb[j]==4)ans++;
        if(xa[i]==3&&xb[j]==0)bns++;
        if(xa[i]==3&&xb[j]==1)bns++;
        if(xa[i]==3&&xb[j]==2)ans++;
        if(xa[i]==3&&xb[j]==4)ans++;
        if(xa[i]==4&&xb[j]==0)ans++;
        if(xa[i]==4&&xb[j]==1)ans++;
        if(xa[i]==4&&xb[j]==2)bns++;
        if(xa[i]==4&&xb[j]==3)bns++;
        }
        cout<<ans<<" "<<bns;
        
        return 0;
}

D - 玩具谜题

在洛谷,享受coding的快乐

因为这里用了一些STL,所以看起来应该比较高级
注释已经差不多了,不做过多的解释

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

int n,m;
vector<string> str;
vector<bool> liwai;//0里1外

int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
        bool a;
		string b;
        cin>>a>>b;
        liwai.push_back(a);
        str.push_back(b);
    }
	
	int num=0;
	while(m--){
        bool zuoyou;//1右(若liwai[i]=0,就+,反之就-)0左 (若liwai[i]=0,就-,反之就+)
        int wei;
        cin>>zuoyou>>wei;
        if(wei!=0){
            if(liwai[num]^zuoyou)//异或符^,不等时为1否则为0。
                num=(num+wei)%n;
            else
                num=(num-wei%n+n)%n;//逆时针 
        }
        
    } 
	cout<<str[num];
	
	return 0;
} 

E - 时间复杂度

一个比较长的模拟题
变量的意义
err语法错误,zimu是否用过,st嵌套,sn复杂度,wuxiao是否有效

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

int t,l;

bool nengxunhuan(string a,string b) {
  if (b=="n")
    return true;
  if (a=="n")
    return false;
  if (a.size()==b.size())
    return a<=b;
  else
    return a.size()<b.size();
}

int main() {
  cin>>t;
  for (int j=1;j<=t;j++) {
    int ans=0;
    bool err=false;
	bool zimu[200];
    stack<char> st,sn,wuxiao;
    memset(zimu,0,sizeof(zimu));
    char c,i;string fzd,x,y;
    cin>>l;
    cin>>fzd;
    for(int k=1;k<=l;k++){
      cin>>c;
      if (c=='E') {
        if (err) continue;
        if (st.empty()){err=true;}//空了读入E,语法错误
        else {
          if (!sn.empty() && st.top()==sn.top())//sn同步出栈
            sn.pop();
          if (!wuxiao.empty() && st.top()==wuxiao.top())//wuxiao同步出栈
            wuxiao.pop();
          zimu[st.top()]=false;
          st.pop();
        }
      }
      if (c=='F') {
        cin>>i>>x>>y;
        if (err) continue;
        if (zimu[i]) {err=true;}
        else if (nengxunhuan(x, y)) {
          st.push(i);
          zimu[i]=true;
          if (x!="n" && y=="n" && wuxiao.empty()) {//当有效且右边是n,左边不同时为n,需要增加复杂度
            sn.push(i);
            if (sn.size()>ans) ans=sn.size();
          }
        }
        else {//无效循环
          st.push(i);
          zimu[i]=true;
          wuxiao.push(i);
        }
      }
    }
    if (!st.empty()) err=true;//缺少E
    if (err) cout<<"ERR"<<endl;
    else {
      if (ans==0 && fzd=="O(1)")
        cout<<"Yes"<<endl;
      else {
        string ss="";
        while(ans>0) {
          ss+=ans%10+'0';
          ans/=10;
        }
        reverse(ss.begin(),ss.end());
        ss="O(n^"+ss+")";
        if (ss==fzd)
          cout<<"Yes"<<endl;
        else
          cout<<"No"<<endl;
      }
    }
  }
  return 0;
}

G - 最大正方形

在洛谷,享受coding的快乐

这是一个dp题
每次看右下角这个位置,如果他等于1.则这个位置等于他的 (正上,左上,左边)的最小值 +1

状态转移方程:
dp[i][j]=min(min(dp[i-1][j-1],dp[i][j-1]),dp[i-1][j])+1

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

int n,m;
int a[110][110];
int dp[110][110];
int ans;

int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]==1){
				dp[i][j]=min(min(dp[i-1][j-1],dp[i][j-1]),dp[i-1][j])+1;
			}
			if(ans<dp[i][j]) ans=dp[i][j];
		}
	}
	
	cout<<ans;
	
	return 0;
} 

H - 地毯

在luogu,享受coding的快乐

众所周知,暴力出奇迹
又短又方便

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

int t[1010][1010];

int main(){
	int n,m,x1,x2,y1,y2;
	cin>>n>>m;
	for(int k=1;k<=m;++k){
		cin>>x1>>y1>>x2>>y2;
		for(int i=x1;i<=x2;++i){
			for (int j=y1;j<=y2;++j){
				++t[i][j];	
			}
		}		
	}
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			cout<<t[i][j]<<" ";	
		}
		cout<<endl;
	}
	
	return 0;
}

J - IncDec Sequence

在luogu,享受coding的快乐

用x[i]来表示差分数组
用t1,t2两个数组来分别存储增的最大值与减的最大值
最后结果就是max(t1,t2)和abs(t1-t2)-1

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

long long n;
long long a[100001],x[100001];
long long t1,t2;

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=2;i<=n;i++){
		x[i]=a[i]-a[i-1];
		if(x[i]>0){
			t1+=x[i];
		}
		else t2-=x[i]; 
	}
	printf("%lld\n%lld",max(t1,t2),abs(t1-t2)+1);
	return 0;
}
posted @ 2022-11-13 16:50  qjc0714  阅读(49)  评论(0)    收藏  举报
html