3. 釘子與木板 (30分)

3. 釘子與木板 (30分)

問題背景

牆上有n個釘子,編號爲1, 2, ..., n。其中釘子i的橫座標爲i,縱座標初始爲xi。可以進行兩種操作:
0 k v:移動操作。豎直移動釘子k,座標變爲(k, v)。
1 s t v:測試操作。若在高度爲v處放一塊橫座標範圍是[s,t]的水平木板,它將下落到什麼高度?換句話說,求出釘子s, s+1, s+2, …, t的縱座標中,不超過v的最大值。如果這些釘子的高度全部大於v,則木板將落到地上,高度爲0。

注意,在測試操作時,水平木板只是用來測試的“臨時木板”,將在測試後立即被拿走,不會影響到後續測試工作。

輸入格式

第一行包含兩個整數n, m,即釘子的個數和操作的個數(1<=n,m<=105)。以下n行每行一個不超過109的非負整數,即xi。以下 m 行爲各操作 (1 <= k <= n, 1 <= s < t <= n, 1 <= v <= 109

輸出格式

按照輸入的順序,對於每個測試操作輸出一個整數,即該測試水平木板的最後高度。

樣例輸入

5 4
1
3
5
7
9
1 2 4 6
0 3 10
1 3 5 7
1 3 5 5

樣例輸出

5
7
0

 

他人解法:

#include<iostream>
#include<map>
#include<cstdlib>
using namespace std;

int main()
{
int n,m;
cin>>n>>m;
int a[m][4],h;
map<int,int> mp;
for(int i=0;i<n;++i)
{
   cin>>h;
   mp[i]=h;
}
int s,t;
for(int i=0;i<m;++i)
{
   int k;
   cin>>a[i][0];
   if(a[i][0]==0) k=3;
    else k=4;
   for(int j=1;j<k;++j)
     cin>>a[i][j];
}
for(int i=0;i<m;++i)
{
if(a[i][0]==1)
   {
    h=a[i][3];
    s=a[i][1];
    t=a[i][2];
    int count=0;
    for(int i=s-1;i<=t-1;++i)
      if(mp[i]>h) ++count;
    if(count==t-s+1) { cout<<0<<endl; continue; }
    int max=0;
    for(int i=s-1;i<=t-1;++i)
      if(mp[i]<=h && mp[i]>max) max=mp[i];
    cout<<max<<endl;
   }
else
{
   s=a[i][1];
   h=a[i][2];
   mp[s-1]=h;
}
}
return 0;
}

 

本人解法:

#include<stdio.h>
int main()
{
 int n,m,i,j,t,k;long a[100001],x,y,z;
 scanf("%d%d",&n,&m);
 for(i=1;i<=n;i++)
  scanf("%d",&a[i]);
 while(m--)
 {
  scanf("%d",&t);
  if(t==1)
  {
   scanf("%d%d%ld",&x,&y,&z);   
   k=x;
      while(a[k]<=z&&k<=y)
    k++;
   if(k==x)
    printf("0");
   else
    printf("%ld",a[k-1]);
   printf("/n");
  }
  else
  {
   scanf("%d%ld",&x,&y);
   if(a[x]>y)
   {
    j=x;
    while(j>=2&&a[j-1]>y)
     a[j--]=a[j-1];
    a[j]=y;
   }
   else
   {
    j=x;
    while(j<n&&a[j+1]<y)
     a[j++]=a[j+1];
    a[j]=y;
   }
  }
 }   
 return 0;
}

發佈了43 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章