1224 -- 【NOIP1997普及组T1】棋盘问题
设有一个N*M方格的棋盘(1<=N<=100,1<=M<=100)
求出该棋盘中包含有多少个正方形、多少个长方形(不包括正方形)。
例如:当 N=2, M=3时: 
正方形的个数有8个:即边长为1的正方形有6个;
边长为2的正方形有2个。
长方形的个数有10个:
即 2*1的长方形有4个:
1*2的长方形有3个:
3*1的长方形有2个:
3*2的长方形有1个:
如上例:输入:2 3
输出:8 10
//一开始没有思路,后来发现直接循环就可以了嘛,判断坐标
//循环顺序不要搞错了
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<set>
using namespace std;
const int maxn=1010;
const int INF=0x3fffffff;
//一开始没有思路,后来发现直接循环就可以了嘛,判断坐标
//循环顺序不要搞错了
int main(){
int n,m;
cin>>n>>m;
int zheng=0,chang=0;
for(int i=0;i<=n;i++){ //从0开始!!!!!!!!
for(int j=0;j<=m;j++){
for(int z=i+1;z<=n;z++){
for(int l=j+1;l<=m;l++){
int c1=z-i;
int c2=l-j;
if(c1==c2) zheng++;
else chang++;
}
}
}
}
cout<<zheng<<" "<<chang<<endl;
return 0;
}
1225 -- 【NOIP1997普及组T2】三角形
将1,2,······,9共9个数排成下列形态的三角形。
其中:a~i分别表示1,2,······,9中的一个数字,并要求同时满足下列条件:
(1)a < f < i;
(2)b < d, g < h, c < e
(3)a+b+d+f=f+g+h+i=i+e+c+a=P
程序要求:
根据输入的边长之和P
输出所有满足上述条件的三角形的个数以及其中的一种方案。
若有多种方案输出字典序最小的那种。若无解输出NO。
//数据规模小,可以直接枚举搜索
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<set>
using namespace std;
const int maxn=1010;
const int INF=0x3fffffff;
//数据规模小,可以直接枚举搜索
int flag[12],res[12],b[12],p;
int judge(int step,int x) { //x是放置的数字,step是位置,函数是用来判断能不能放的
if(flag[x]==1) return 0;
if(step==2||step==3||step==7) return 1;//因为对这三个位置没有要求
if(step==4) return x>b[2];
if(step==5) return x>b[3];
if(step==6) return (x>b[1])&&(x+b[1]+b[2]+b[4]==p);
if(step==8) return x>b[7];
if(step==9) return (x>b[6])&&(x+b[1]+b[3]+b[5]==p)&&(b[6]+b[7]+b[8]+x==p);
}
int ans=0;
void dfs(int step) {
if(step>=9) {
ans++;
if(ans==1) { //保存第一次
for(int i=1; i<=9; i++) res[i]=b[i];
return;
}
}
for(int i=1; i<=9; i++) {
if(judge(step+1,i)) { //如果可以放
flag[i]=1;
b[step+1]=i;
dfs(step+1);
flag[i]=0;
}
}
}
int main() {
cin>>p;
for(int i=1; i<=9; i++) {
flag[i]=1;
b[1]=i; //从不同初值开始尝试:数据规模小
dfs(1);
flag[i]=0; //回溯
}
if(ans==0) {
cout<<"NO"<<endl;
return 0;
} else {
cout<<ans<<endl;
//for(int i=1;i<=9;i++) cout<<res[i]<<" ";
cout<<res[1]<<endl;
cout<<res[2]<<" "<<res[3]<<endl;
cout<<res[4]<<" "<<res[5]<<endl;
cout<<res[6]<<" "<<res[7]<<" "<<res[8]<<" "<<res[9]<<endl;
}
return 0;
}
1226 -- 【NOIP1997普及组T3】街道问题
设有一个N*M(l<= N<=30, l<= M<= 30)的街道(如图一):
规定行人从A(1,1)出发,在街道上只能向东或北方向行走。
图二为N=3,M=3的街道图,从A出发到达B共有6条可供行走的路径:
1. A-A1-A2-A5-B
2. A-A1-A4-A5-B
3. A-A1-A4-A7-B
4. A-A3-A4-A5-B
5. A-A3-A4-A7-B
6. A-A3-A6-A7-B
若在N*M的街道中,设置一个矩形障碍区域(包括围住该区域的的街道)不让行人通行,如图一中用“*”表示的部分。
此矩形障碍区域用2对顶点坐标给出,图一中的2对顶点坐标为:(2,2),(8,4),此时从A出发到达B的路径仅有两条。
程序要求
任务一:给出N,M后,求出所有从A出发到达B的路径的条数。
任务二:给出N,M,同时再给出此街道中的矩形障碍区域的2对顶点坐标(X1,Y1),
(X2,Y2),然后求出此种情况下所有从A出发到达B的路径的条数。
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<queue>
#include<map>
#include<vector>
#include<set>
using namespace std;
const int maxn=1010;
const int INF=0x3fffffff;
int a[50][50];
int flag,n,m,num=0;
int vis[50][50];
int sx,sy,ex,ey;
int diss[2][2]={{0,1},{1,0}};
long long f[31][31];
void dfs(int x,int y){
if(x==n&&y==m){
num++;
return;
}
for(int i=0;i<2;i++){
int xx=x+diss[i][0],yy=y+diss[i][1];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&vis[xx][yy]==0){
vis[xx][yy]=1;
dfs(xx,yy);
vis[xx][yy]=0;
}
}
}
int main(){
cin>>flag>>n>>m;
if(flag==1){ ///任务1:就是简单的递推
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1&&j==1) f[i][j]=1;
else if(i==1) f[i][j]=f[i][j-1];
else if(j==1) f[i][j]=f[i-1][j];
else f[i][j]=f[i-1][j]+f[i][j-1];
}
}
cout<<f[n][m];
}
else{
cin>>sx>>sy>>ex>>ey;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i>=sx&&i<=ex&&j>=sy&&j<=ey) { //任务二也是枚举,只是有些地方要设为0
f[i][j]=0;
continue;
}
else if(i==1&&j==1) f[i][j]=1;
else if(i==1) f[i][j]=f[i][j-1];
else if(j==1) f[i][j]=f[i-1][j];
else f[i][j]=f[i-1][j]+f[i][j-1];
}
}
cout<<f[n][m]<<endl;
}
return 0;
}
posted on
浙公网安备 33010602011771号