ZOJ 刷题集
开始刷ZOJ,希望能有一个新的开始,新的机会
2019/11/21
开始刷ZOJ,希望能有一个新的开始,新的机会
题意 : 大致就是一个矩阵模型,X为墙,保证每个人都不能相互看到,求这种情况下的可以最多加入的人的个数
题解 : 大致推算出复杂度,暴力解决问题
/*
* 2019/11/21 * 因为N最大为4,所以可以枚举所有情况,复杂度为2^(N*N)
* 暴力求解
*/
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 5;
char s[MAXN][MAXN];
int t[MAXN][MAXN];
int N;
int max(int a,int b){
return a>b?a:b;
}
int row(int x,int y){
for(int i=x+1;i<N;i++){
if(s[i][y]=='X')break;
if(t[i][y])return 0;
}
for(int i=x-1;i>=0;i--){
if(s[i][y]=='X')break;
if(t[i][y])return 0;
}
return 1;
}
int cloumn(int x,int y){
for(int i=y+1;i<N;i++){
if(s[x][i]=='X')break;
if(t[x][i])return 0;
}
for(int i=y-1;i>=0;i--){
if(s[x][i]=='X')break;
if(t[x][i])return 0;
}
return 1;
}
int slove(int M){
int cnt=0;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
cnt+=M%2;
t[i][j]=M%2;
M/=2;
if(t[i][j]&&s[i][j]=='X')return 0;
}
}
// for(int i=0;i<N;i++){
// for(int j=0;j<N;j++){
// printf("%d ",t[i][j]);
// }
// printf("\n");
// }
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
if(t[i][j]){
if(row(i,j)&&cloumn(i,j));
else return 0;
}
}
}
return cnt;
}
int main(){
while(scanf("%d",&N)!=EOF&&N){
int maxx=0;
for(int i=0;i<N;i++)
scanf("%s",s[i]);
// for(int i=0;i<N;i++)
// printf("%s\n",s[i]);
for(int i=0;i<1<<(N*N);i++){
memset(t,0,sizeof(t));
maxx=max(maxx,slove(i));
}
printf("%d\n",maxx);
}
return 0;
}
ZOJ 1003
题意:标有序号1~100的100个气球,两个人扎,每个人的分数为自己所扎气球的成绩,现在给出两个人的成绩,成绩低的人要申诉,如果申诉成功输出低成绩,否则输出高的成绩。(申诉条件:说出自己所扎的气球,证明高成绩无法的到改成绩)
题解:从1~100个气球递归遍历一遍,看是否满足低成绩的申诉。
/**
* 题意难理解,看了好久 2333
**/
#include <cstdio>
#include <cstring>
using namespace std;
bool fa,fb;
void bfs(int a,int b,int k){
if(b==1){
fb=true;
if(a==1)fa=true;
}
if(k==1||(fa&&fb))return;
if(a%k==0){
bfs(a/k,b,k-1);
}
if(b%k==0){
bfs(a,b/k,k-1);
}
bfs(a,b,k-1);
}
int main(){
int N,M;
while (scanf("%d%d",&N,&M)!=EOF&&(N||M)){
if(N<M){
int temp=N;
N=M;
M=temp;
}
fa=false;
fb=false;
bfs(N,M,100);
if(fb&&!fa)printf("%d\n",M);
else printf("%d\n",N);
}
return 0;
}
ZOJ 1004
题意:给两个单词A、B,一个栈,写出所有的进栈出栈的操作,枚举出所有的进出栈结果。
题解:模拟求一遍,递归 + 栈。
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
vector<char>x;
stack<int>y;
string s,t;
void DFS(int a,int b,int len){
if(a==len&&b==len){
for(int i=0;i<x.size();i++){
cout<<x[i]<<" ";
}
cout<<endl;
return;
}
if(a<len){
x.push_back('i');
y.push(s[a]);
DFS(a+1,b,len);
y.pop();
x.pop_back();
}
if(b<len&&!y.empty()&&y.top()==t[b]){
char xx=y.top();
y.pop();
x.push_back('o');
DFS(a,b+1,len);
y.push(xx);
x.pop_back();
}
}
int main(){
while(cin>>s>>t){
x.clear();
while(!y.empty())y.pop();
cout<<"["<<endl;
DFS(0,0,s.length());
cout<<"]"<<endl;
}
return 0;
}
ZOJ 1005
题意:经典的倒水问题
题解:辗转相减法
/* *
* 2019/11/22 * 拓展欧几里得,使用辗转相减解决
* */
#include <cstdio>
using namespace std;
int main(){
int A,B,C;
while(scanf("%d%d%d",&A,&B,&C)!=EOF){
int b=0;
if(B==C){
printf("fill B\n");
}
else
while(b!=C){
printf("fill A\npour A B\n");
b=A+b;
if(b>=B){
printf("empty B\npour A B\n");
b-=B;
}
}
printf("success\n");
}
return 0;
}