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老题了,代码量有点大,所以,,就不上代码了我不会告诉你们我懒得写。

  • 相关阅读:
    DateTime类型的一个Bug
    无痛苦的软件维护——被遗忘的需求
    完全命令行.NET开发
    无痛苦的软件维护——文档和代码
    .NET初学者架构设计指南(一)Hello world的时代
    NGOSS的一点简单概念
    软件的逻辑层次
    VSTS for Testers学习笔记目录
    How Google Tests Software (出书,停止更新)
    推荐——《浪潮之巅》(据传稍后会出书,停止更新)
  • 原文地址:https://www.cnblogs.com/SXia/p/6863626.html
Copyright © 2011-2022 走看看