Codeforces 611C
2016-01-07 20:19
183 查看
题目链接:http://codeforces.com/problemset/problem/611/C
C:
一个矩阵(500*500),有些障碍点和空格点。
现在可以放一种1*2的骨牌,骨牌只能放在空格点。
问对于(x1,y1,x2,y2)这个矩阵,有多少种合法的放骨牌的方式。
很明显的dp[x2][y2] + dp[x1][y1] - dp[x2][y1] - dp[x1][y2]的模式,因为骨牌横竖放置的不一样所以稍微调一下下标就可以。
一.
刚开始想的时候想一下子把二维的答案直接存下来,但显然这样子是没法递推的,所以只能横着算一遍纵着算一遍,不过就是这样相比一维的话,记录的是以i,j为右下角的横或纵的数量,也就是说表示的是一个矩形的,而一维的话表示的是一行或者一列的,所以说只需要在处理的时候,把横或者纵的那条边去掉就可以了,不要多减就可以了!!!
二.用一维前缀和优化的时候,居然卡在了一个坑上,即sum[x2]-sum[x1],而不是x1-1,太坑了,这bug很是不好找啊!!!
二维的代码:
C:
一个矩阵(500*500),有些障碍点和空格点。
现在可以放一种1*2的骨牌,骨牌只能放在空格点。
问对于(x1,y1,x2,y2)这个矩阵,有多少种合法的放骨牌的方式。
很明显的dp[x2][y2] + dp[x1][y1] - dp[x2][y1] - dp[x1][y2]的模式,因为骨牌横竖放置的不一样所以稍微调一下下标就可以。
一.
刚开始想的时候想一下子把二维的答案直接存下来,但显然这样子是没法递推的,所以只能横着算一遍纵着算一遍,不过就是这样相比一维的话,记录的是以i,j为右下角的横或纵的数量,也就是说表示的是一个矩形的,而一维的话表示的是一行或者一列的,所以说只需要在处理的时候,把横或者纵的那条边去掉就可以了,不要多减就可以了!!!
二.用一维前缀和优化的时候,居然卡在了一个坑上,即sum[x2]-sum[x1],而不是x1-1,太坑了,这bug很是不好找啊!!!
[code]#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=5e2+10; char a[maxn][maxn]; int n,m; int sumrow[maxn][maxn],sumcol[maxn][maxn]; int main(){ cin>>n>>m; for(int i=1;i<=n;i++){ scanf("%s",a[i]+1); } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i][j]=='.'&&a[i][j-1]=='.'){ sumrow[i][j]=sumrow[i][j-1]+1; } else sumrow[i][j]=sumrow[i][j-1]; } } for(int j=1;j<=m;j++){ for(int i=1;i<=n;i++){ if(a[i][j]=='.'&&a[i-1][j]=='.'){ sumcol[i][j]=sumcol[i-1][j]+1; } else sumcol[i][j]=sumcol[i-1][j]; } } int q,x1,y1,x2,y2;scanf("%d",&q); while(q--){ int sum=0; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); for(int i=x1;i<=x2;i++){ sum+=sumrow[i][y2]-sumrow[i][y1]; } for(int i=y1;i<=y2;i++){ sum+=sumcol[x2][i]-sumcol[x1][i]; } printf("%d\n",sum); } return 0; }
二维的代码:
[code] #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=5e2+10; char a[maxn][maxn]; int n,m; int sumrow[maxn][maxn],sumcol[maxn][maxn]; int main(){ cin>>n>>m; for(int i=1;i<=n;i++){ scanf("%s",a[i]+1); } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ sumrow[i][j]=sumrow[i][j-1]+sumrow[i-1][j]-sumrow[i-1][j-1]; sumcol[i][j]=sumcol[i][j-1]+sumcol[i-1][j]-sumcol[i-1][j-1]; if(a[i][j]=='.'&&a[i][j-1]=='.') sumrow[i][j]++; if(a[i][j]=='.'&&a[i-1][j]=='.') sumcol[i][j]++; } } int q,x1,y1,x2,y2;scanf("%d",&q); while(q--){ int sum=0; scanf("%d%d%d%d",&x1,&y1,&x2,&y2); sum+=sumrow[x2][y2]-sumrow[x1-1][y2]-sumrow[x2][y1]+sumrow[x1-1][y1]; sum+=sumcol[x2][y2]-sumcol[x1][y2]-sumcol[x2][y1-1]+sumcol[x1][y1-1]; printf("%d\n",sum); } return 0; }
相关文章推荐
- Intent七大属性
- Plus One leetcode
- Jquery自定义一个带名称的、可以传参数的函数以及setTimeout延迟调用,用法详解
- 求int型数据在内存中存储时1的个数
- cf#336-B-Hamming Distance Sum
- 安卓核心六Intent对象
- 店小二的总结
- Java多线程-实现多线程的两种方式
- php7新特性
- 安卓核心五application组件
- Coreball的小游戏
- Linux zip命令
- 人体美化的一些处理图像处理
- 动态规划-寻找最优分配时间。(未理解)
- IO_其他流_基本数据类型+String处理流JAVA158
- Oracl 动态执行表不可访问,本会话的自动统计被禁止
- 手机app测试分析方法 -- 进阶方法
- 安卓核心组件四BroadCastReceiver
- 冒泡排序
- UISearchBar协议常用方法