啊哈哈哈哈哈哈哈哈哈哈哈哈,先让我笑会。。。ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh,好了不玩了。。。
这题昨天开始做,刚一开始看题就觉得下标难处理,果不其然就是一场腥风暴雨,各种表示不对。其实我最怕下标多的题了,看多了就晕。害得我昨天晚上也没睡好(这是第二天补得)。虽然数据不大,但我用了4层for,应该不是最好算法,不过好歹A了(本以为凶多吉少)。输出也有点麻烦,他的那一层星号是两组数据间输出,而不是有有效解输出,英语太差啊。。。总的来说,模拟这玩意没什么高深思想,就是在脑子里构建模型,而且要一遍遍模拟找错,才能成功。
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <set>
#include <vector>
#include <string>
#include <sstream>
#include <ctype.h>
#include <string.h>
using namespace std;
const int N = 10;
const int INF = 1000000;
int hor[N][N];
int ver[N][N];
int main()
{
// freopen("in.txt", "r", stdin);
int T = 0, dot, edge, x, y, ans[15], Case = 1;
char c[5];
while(~scanf("%d%d", &dot, &edge))
{
memset(hor, 0, sizeof(hor));
memset(ver, 0, sizeof(ver));
memset(ans, 0, sizeof(ans));
while(edge --)
{
cin >> c;
scanf("%d%d", &x, &y);
if(c[0] == 'H') hor[x][y] = 1;
else if(c[0] == 'V') ver[y][x] = 1;
}
int sta = dot - 1;//标准化
if(T ++) printf("\n**********************************\n\n");
/* for(int i = 1; i <= dot; i ++)
{
for(int j = 1; j <= sta; j ++)
printf("%d ", hor[i][j]);
printf("\n");
}
for(int i = 1; i <= sta; i ++)
{
for(int j = 1; j <= dot; j ++)
printf("%d ", ver[i][j]);
printf("\n");
}*/
for(int i = 1; i <= sta; i ++) //边长度的延伸
{
for(int j = 1; j + i <= dot; j ++)//判断行
{
for(int k = 1; k + i <= dot; k ++)//判断列
{
int flag = 1;
for(int l = 0; l <= i; l += i)
for(int m = 0; m <= i - 1; m ++)
{
if(hor[j + l][k + m] == 0)
{
flag = 0;
// printf("fuck1");
// printf("fuck1---<%d, %d>\n", j + l, k + m);
break;
}
}
for(int l = 0; l <= i - 1; l ++)
for(int m = 0; m <= i; m += i)
{
if(ver[j + l][k + m] == 0)
{
flag = 0;
// printf("fuck2---<%d, %d>\n", j + l, k + m);
break;
}
}
if(flag == 1) { ans[i] ++;/* printf("可行解:<%d, %d>\n", j, k); */}
}
}
}
printf("Problem #%d\n\n", Case ++);
int flag1 = 0;
for(int i = 1; i <= sta; i ++)
{
if(ans[i])
{
printf("%d square (s) of size %d\n", ans[i], i);
flag1 = 1;
}
}
if(!flag1) printf("No completed squares can be found.\n");
}
return 0;
}
但是,换到poj上1500的数据量就超时了,剪枝也不行,看来以后想出好算法还要再优化下哈~
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cmath>
#include <set>
#include <vector>
#include <string>
#include <sstream>
#include <ctype.h>
#include <string.h>
using namespace std;
const int N = 1505;
const int INF = 1000000;
int hor[N][N];
int ver[N][N];
int main()
{
// freopen("in.txt", "r", stdin);
int dot, edge, x, y1, y2, ans[1505];
char c[5];
while(~scanf("%d%d", &dot, &edge))
{
memset(hor, 0, sizeof(hor));
memset(ver, 0, sizeof(ver));
memset(ans, 0, sizeof(ans));
while(edge --)
{
cin >> c;
scanf("%d%d%d", &x, &y1, &y2);
if(c[0] == 'H')
{
for(int i = 0; i < y2; i ++)
hor[x][y1 + i] = 1;
}
else if(c[0] == 'V')
{
for(int i = 0; i < y2; i ++)
ver[x + i][y1] = 1;
}
}
int sta = dot - 1;//标准化
/* for(int i = 1; i <= dot; i ++)
{
for(int j = 1; j <= sta; j ++)
printf("%d ", hor[i][j]);
printf("\n");
}
for(int i = 1; i <= sta; i ++)
{
for(int j = 1; j <= dot; j ++)
printf("%d ", ver[i][j]);
printf("\n");
}*/
for(int i = 1; i <= sta; i ++) //边长度的延伸
{
for(int j = 1; j + i <= dot; j ++)//判断行
{
for(int k = 1; k + i <= dot; k ++)//判断列
{
int flag = 1;
for(int l = 0; l <= i; l += i)
{
for(int m = 0; m <= i - 1; m ++)
{
if(hor[j + l][k + m] == 0)
{
flag = 0;
// printf("fuck1");
// printf("fuck1---<%d, %d>\n", j + l, k + m);
break;
}
}
if(flag == 0) break;
}
if(flag != 0)
{
for(int l = 0; l <= i - 1; l ++)
{
for(int m = 0; m <= i; m += i)
{
if(ver[j + l][k + m] == 0)
{
flag = 0;
// printf("fuck2---<%d, %d>\n", j + l, k + m);
break;
}
}
if(flag == 0) break;
}
}
if(flag == 1) { ans[i] ++;/* printf("可行解:<%d, %d>\n", j, k); */}
}
}
}
int sum = 0;
for(int i = 1; i <= sta; i ++)
{
sum += ans[i];
}
printf("%d\n", sum);
}
return 0;
}