zoukankan      html  css  js  c++  java
  • 20170515测试

    问题 A: 棋盘覆盖问题

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    在一个2^k×2^k个方格组成的棋盘中恰有一个方格与其它方格不同(图中标记为-1的方格),称之为特殊方格。现用L型(占3个小方格)纸片覆盖棋盘上除特殊方格的所有部分,各纸片不得重叠,于是,用到的纸片数恰好是(4^k-1)/3。在下表给出的一个覆盖方案中,k=2,相同的3各数字构成一个纸片。  
    下面使用分治法设计的,将棋盘一分为四,依次处理左上角、右上角、左下角、右下角,递归进行。输出最后的棋盘。

    输入

    输入文件共2行。
    第1行:  一个整数k,表示一个2^k×2^k个方格组成的棋盘。
    第2行:两个整数,dr,dc,表示坐标为(dr,dc)的方格为特殊方格。
     

    输出

    摆放好数字后的,2^k×2^k个方格组成的棋盘

    样例输入

    2
    2 2

    样例输出

    2 2 3 3
    2 -1 1 3
    4 1 1 5
    4 4 5 5

    提示

    【数据范围】

    50%的数据k<=5。

    100%的数据k<=10。

    题解:分治,将原问题分为形式相同,规模更小的子问题。

    将棋盘分成4份,在中间交界构造出一块纸片,使得每块里均有一个特殊方格。

     1 #include <iostream>
     2 #include <cstdio>
     3 #define N 2100
     4 using namespace std;
     5 int map[N][N],n,bx,by,cnt;
     6 void dfs(int x,int y,int xx,int yy,int k)
     7 {
     8     if (x+1==xx)
     9     {
    10         ++cnt;
    11         if (k!=1)    map[x][y]=cnt;
    12         if (k!=2)    map[x][yy]=cnt;
    13         if (k!=3)    map[xx][y]=cnt;
    14         if (k!=4)    map[xx][yy]=cnt;
    15         return;                
    16     }
    17     int ox=(x+xx)>>1,oy=(y+yy)>>1,o=(xx-x+1)>>2,po,temp;
    18     if (k==0)
    19     {
    20         if (bx<=ox && by<=oy)    po=1;
    21         else if (bx<=ox)    po=2;
    22         else if (by<=oy)    po=3;
    23         else po=4;
    24         dfs(ox-o+1,oy-o+1,ox+o,oy+o,po);
    25         if (po==1)    temp=0;else temp=4;
    26         dfs(x,y,ox,oy,temp);
    27         if (po==2)    temp=0;else temp=3;
    28         dfs(x,oy+1,ox,yy,temp);
    29         if (po==3)    temp=0;else temp=2;
    30         dfs(ox+1,y,xx,oy,temp);
    31         if (po==4)    temp=0;else temp=1;
    32         dfs(ox+1,oy+1,xx,yy,temp);
    33     }
    34     else
    35     {
    36         dfs(ox-o+1,oy-o+1,ox+o,oy+o,k);
    37         if (k!=1)    dfs(x,y,ox,oy,4);
    38         if (k!=2)    dfs(x,oy+1,ox,yy,3);
    39         if (k!=3)    dfs(ox+1,y,xx,oy,2);
    40         if (k!=4)    dfs(ox+1,oy+1,xx,yy,1);
    41     }
    42 }
    43 void solve()
    44 {
    45     cin>>n>>bx>>by;
    46     n=1<<n;
    47     dfs(1,1,n,n,0);
    48 }
    49 void print()
    50 {
    51     map[bx][by]=-1;
    52     for (int i=1;i<=n;++i)
    53         for (int j=1;j<=n;++j)
    54             if (j<n)    printf("%d ",map[i][j]);
    55             else printf("%d
    ",map[i][j]);
    56 }
    57 int main()
    58 {
    59     solve();
    60     print();
    61     return 0;
    62 }
    View Code

    问题 B: 上帝造题的七分钟

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵。
    第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作。
    第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作。
    第四分钟,彩虹喵说,要基于二叉树的数据结构,于是便有了数据范围。
    第五分钟,和雪说,要有耐心,于是便有了时间限制。
    第六分钟,吃钢琴男说,要省点事,于是便有了保证运算过程中及最终结果均不超过32位有符号整数类型的表示范围的限制。
    第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。”
           ——《上帝造裸题的七分钟》
    所以这个神圣的任务就交给你了。

    输入

    输入数据的第一行为X n m,代表矩阵大小为n×m。
    从输入数据的第二行开始到文件尾的每一行会出现以下两种操作:
    L a b c d delta ——代表将(a,b),(c,d)为顶点的矩形区域内的所有数字加上delta
    k a b c d——代表求(a,b),(c,d)为顶点的矩形区域内所有数字的和
     
    请注意,k为小写。

    输出

    针对每个k操作,在单独的一行输出答案。

    样例输入

    X 4 4
    L 1 1 3 3 2
    L 2 2 4 4 1
    k 2 2 3 3

    样例输出

    12

    提示

    【数据范围】

    对于100%的数据,1 ≤ n ≤ 2048, 1 ≤ m ≤ 2048, 1 ≤ abs(delta) ≤ 500,操作不超过200000个,保证运算过程中及最终结果均不超过32位带符号整数类型的表示范围。

     裸题,二维树状数组
     
     
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<cstdlib>
     7 #include<vector>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef long double ld;
    11 typedef pair<int,int> pr;
    12 const double pi=acos(-1);
    13 #define rep(i,a,n) for(int i=a;i<=n;i++)
    14 #define per(i,n,a) for(int i=n;i>=a;i--)
    15 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
    16 #define clr(a) memset(a,0,sizeof(a))
    17 #define pb push_back
    18 #define mp make_pair
    19 #define fi first
    20 #define sc second
    21 #define pq priority_queue
    22 #define pqb priority_queue <int, vector<int>, less<int> >
    23 #define pqs priority_queue <int, vector<int>, greater<int> >
    24 #define vec vector
    25 ld eps=1e-9;
    26 ll pp=1000000007;
    27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
    28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
    29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
    30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; }
    31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
    32 ll read(){ ll ans=0; char last=' ',ch=getchar();
    33 while(ch<'0' || ch>'9')last=ch,ch=getchar();
    34 while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    35 if(last=='-')ans=-ans; return ans;
    36 }
    37 int n,m;
    38 #define N 2100
    39 #define lowbit(i) (i&(-i))
    40 int t_1[N][N],t_2[N][N],t_3[N][N],t_4[N][N];
    41 void add(int x,int y,int v_1,int v_2,int v_3,int v_4){
    42     for (int i=x;i<=n;i+=lowbit(i))
    43         for (int j=y;j<=m;j+=lowbit(j)) t_1[i][j]+=v_1,t_2[i][j]+=v_2,t_3[i][j]+=v_3,t_4[i][j]+=v_4;
    44 } 
    45 int sum(int x,int y){
    46     int Sum1=0,Sum2=0,Sum3=0,Sum4=0;
    47     for (int i=x;i>0;i-=lowbit(i))
    48         for (int j=y;j>0;j-=lowbit(j)) Sum1+=t_1[i][j],Sum2+=t_2[i][j],Sum3+=t_3[i][j],Sum4+=t_4[i][j];
    49     return Sum1*x*y-Sum2*x-Sum3*y+Sum4;
    50 }
    51 int main()
    52 {
    53     char ch[10]; scanf("%s%d%d",ch,&n,&m);
    54     while (~scanf("%s",ch)){
    55         if (ch[0]=='L'){
    56             int a,b,c,d,v; scanf("%d%d%d%d%d",&a,&b,&c,&d,&v);
    57             add(a,b,v,v*(b-1),v*(a-1),v*(a-1)*(b-1)); add(a,d+1,-v,(-v)*d,(-v)*(a-1),(-v)*d*(a-1));
    58             add(c+1,b,-v,(-v)*(b-1),(-v)*c,(-v)*c*(b-1)); add(c+1,d+1,v,v*d,v*c,v*d*c);
    59         } else {
    60             int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d);
    61             printf("%d
    ",sum(c,d)-sum(a-1,d)-sum(c,b-1)+sum(a-1,b-1)); 
    62         }
    63     } 
    64     return 0;
    65  } 
    View Code

    问题 C: 最优贸易简化版

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    C国有n座城市,编号是1到n,编号为i的城市有路到编号为i+1的城市(编号为n的城市没有路到其他的城市)。
    C国幅员辽阔,各地的资源分布情况各不相同,这就导致了同一种商品在不同城市的价格不一定相同。但是,同一种商品在同一个城市的买入价和卖出价始终是相同的。
    商人阿龙再次来到C国旅游。他还是想贩卖水晶赚取旅费,在某个城市买入,再另一个城市卖出。
    他将从编号为a的城市到编号到b的城市。请你帮他算算,最多能赚多少钱。
    注:他最多进行一次买入和一次卖出。

    输入

    第一行两个整数n和m,表示n个城市和m个询问。
    第二行n个整数,表示n座城市水晶的买入和卖出的价格。
    接下来m行,每行两个整数a、b,表示阿龙要从编号为a的城市到编号为b的城市(a<b);

    输出

    对于每个询问输出阿龙能赚多少钱。

    样例输入

    6 3 2 1 3 6 4 5 1 2 2 4 1 6

    样例输出

    0 5 5

    提示

    【输出输出样例解释】

    从1到2,无法赚钱。

    从2到4,在编号为2的城市买入,在编号为4的城市卖出。

    从1到6,在编号为2的城市买入,在编号为4的城市卖出。

    对于20%的数据,n和m的范围[1,500];

    对于40%的数据,n和m的范围[1,5000];

     

    【数据范围】

    对于20%的数据,n和m的范围[1,500];

    对于40%的数据,n和m的范围[1,5000];

    对于70%的数据,n和m的范围[1,50000];

    对于100%的数据,n和m的范围[1,500000];

     类似RMQ问题(可以用ST表解决):

    最小买入价格Mi[i][j] = min(Mi[i][j - 1]; Mi[i + 2j-1][j - 1]);

    最大卖出价格Mx[i][j] = max(Mx[i][j - 1]; Mx[i + 2j-1][j - 1]);

    最大收益F[i][j] = maxfF[i][j - 1]; F[i + 2j-1][j - 1],Mx[i + 2j-1][j - 1] - Mi[i][j - 1];

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<cstdlib>
     7 #include<vector>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef long double ld;
    11 typedef pair<int,int> pr;
    12 const double pi=acos(-1);
    13 #define rep(i,a,n) for(int i=a;i<=n;i++)
    14 #define per(i,n,a) for(int i=n;i>=a;i--)
    15 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
    16 #define clr(a) memset(a,0,sizeof(a))
    17 #define pb push_back
    18 #define mp make_pair
    19 #define fi first
    20 #define sc second
    21 #define pq priority_queue
    22 #define pqb priority_queue <int, vector<int>, less<int> >
    23 #define pqs priority_queue <int, vector<int>, greater<int> >
    24 #define vec vector
    25 ld eps=1e-9;
    26 ll pp=1000000007;
    27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
    28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
    29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
    30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; }
    31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
    32 ll read(){ ll ans=0; char last=' ',ch=getchar();
    33 while(ch<'0' || ch>'9')last=ch,ch=getchar();
    34 while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    35 if(last=='-')ans=-ans; return ans;
    36 }
    37 int n,m;
    38 int f_a[500005][20],f_i[500005][20],f[500005][20],l[500005];
    39 void Build(){
    40     for (int i=1;i<=n;i++) {
    41         scanf("%d",&f_a[i][0]); f_i[i][0]=f_a[i][0]; f[i][0]=0;
    42     }
    43     for (int j=1;(1<<j)<n;j++) 
    44         for (int i=1;i+(1<<j)-1<=n;i++){
    45             f_a[i][j]=max(f_a[i][j-1],f_a[i+(1<<(j-1))][j-1]);
    46             f_i[i][j]=min(f_i[i][j-1],f_i[i+(1<<(j-1))][j-1]);
    47             f[i][j]=max(max(f[i][j-1],f[i+(1<<(j-1))][j-1]),f_a[i+(1<<(j-1))][j-1]-f_i[i][j-1]);
    48     }
    49 }
    50 int Query_(int a,int b){
    51     if (a>b) return 0;
    52     int k=l[b-a+1];
    53     return max(f_a[a][k],f_a[b-(1<<k)+1][k]);
    54 }
    55 int Query(int a,int b){
    56     if (a>=b) return 0;
    57     int k=l[b-a+1];
    58     return max(f[a][k],max(Query(a+(1<<k),b),Query_(a+(1<<k),b)-f_i[a][k]));
    59 }
    60 int main()
    61 {
    62     scanf("%d%d",&n,&m);
    63     for (int i=1;i<=500000;i++)
    64         l[i]=log(i)/log(2); 
    65     Build();
    66     while (m--){
    67         int a,b; scanf("%d%d",&a,&b);
    68         printf("%d
    ",Query(a,b));
    69     }
    70     return 0;
    71  } 
    View Code

    问题 D: 维护数列

    时间限制: 1 Sec  内存限制: 128 MB

    题目描述

    输入

    输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
    第2行包含N个数字,描述初始时的数列。
    以下M行,每行一条命令,格式参见问题描述中的表格。
    任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
    插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。

    输出

    对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。

    样例输入

    9 8 2 -6 3 5 1 -5 -3 6 3 GET-SUM 5 4 MAX-SUM INSERT 8 3 -5 7 2 DELETE 12 1 MAKE-SAME 3 3 2 REVERSE 3 6 GET-SUM 5 4 MAX-SUM

    样例输出

    -1 10 1 10

    提示


    【数据范围】

    你可以认为在任何时刻,数列中至少有 1 个数。 输入数据一定是正确的,即指定位置的数在数列中一定存在。

    50%的数据中,任何时刻数列中最多含有 30 000 个数; 100%的数据中,任何时刻数列中最多含有 500 000 个数。

    100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。


    100%的数据中,M ≤20 000,插入的数字总数不超过 4 000 000 个,输入文件 大小不超过 20MBytes。

     splay老题了,代码量有点大,所以,,就不上代码了我不会告诉你们我懒得写。

  • 相关阅读:
    为什么 PCB 生产时推荐出 Gerber 给工厂?
    Fedora Redhat Centos 有什么区别和关系?
    【KiCad】 如何给元件给元件的管脚加上划线?
    MCU ADC 进入 PD 模式后出现错误的值?
    FastAdmin 生产环境升级注意
    EMC EMI 自行评估记录
    如何让你的 KiCad 在缩放时不眩晕?
    KiCad 5.1.0 正式版终于发布
    一次单片机 SFR 页引发的“事故”
    java基础之集合
  • 原文地址:https://www.cnblogs.com/SXia/p/6863626.html
Copyright © 2011-2022 走看看