给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过。给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案。在迷宫中移动有上下左右四种方式,每次只能移动一个方格。数据保证起点上没有障碍。
第一行N、M和T,N为行,M为列,T为障碍总数。第二行起点坐标SX,SY,终点坐标FX,FY。接下来T行,每行为障碍点的坐标。
给定起点坐标和终点坐标,问每个方格最多经过1次,从起点坐标到终点坐标的方案总数。
2 2 1
1 1 2 2
1 2
1
【数据规模】
1≤N,M≤5
虽然只是个普通的dfs。。我wa了三次,然后血与泪的教训是我没有把起点标记为1(已走过)
然后一直40分!!!忍不住看了题解...啊大佬们说40分就是起点没标记的结果!!!我恨
#include
using namespace std;
int a[6][6];
int cnt;
int sx,sy,fx,fy;
int n,m,t;
int dir[4][2]={
{0,1},
{0,-1},
{1,0},
{-1,0},
};
void dfs(int x,int y){
if(x == fx && y == fy){
cnt++;
return;
}
for(int i = 0;i < 4;i++){
x += dir[i][0];
y += dir[i][1];
if(a[x][y] == 0 && x >= 1 && x <= n && y >= 1 && y <= m){
a[x][y] = 1;
dfs(x,y);
a[x][y] = 0;
}
x -= dir[i][0];
y -= dir[i][1];
}
return;
}
int main(){
cin >> n >> m >> t;
cin >> sx >> sy >> fx >> fy;
memset(a,0,sizeof(a));
a[sx][sy] = 1;
while(t--){
int c,d;
cin >> c >> d;
a[c][d] = 1;
}
cnt = 0;
// for(int i = 1;i <= n;i++){
// for(int j = 1;j <= m;j++){
// printf("%d ",a[i][j]);
// }
// printf("\n");
// }
dfs(sx,sy);
cout << cnt << endl;
return 0;
}
有一个仅由数字00与11组成的n \times nn×n格迷宫。若你位于一格0上,那么你可以移动到相邻44格中的某一格11上,同样若你位于一格1上,那么你可以移动到相邻44格中的某一格00上。
你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身)。
第11行为两个正整数n,mn,m。
下面nn行,每行nn个字符,字符只可能是00或者11,字符之间没有空格。
接下来mm行,每行22个用空格分隔的正整数i,ji,j,对应了迷宫中第ii行第jj列的一个格子,询问从这一格开始能移动到多少格。 然后T行,每行为一个数N(1<=N<=1000000)表示长方形的大小。
m行,对于每个询问输出相应答案。
2 2
01
10
1 1
2 2
4
4
所有格子互相可达。
对于20%20%的数据,n≤10n≤10;
对于40%40%的数据,n≤50n≤50;
对于50%50%的数据,m≤5m≤5;
对于60%60%的数据,n≤100,m≤100n≤100,m≤100;
对于100%100%的数据,n≤1000,m≤100000n≤1000,m≤100000。
这一题我起先细节错误没有加=然后我就wa了,当然wa中还坚定地带着三个tle
然后我康了好久的代码,改完后其他的样例都A了,顽强的三个tle依旧在,果然是查询次数太多了不能一次次查询么
然后就默默改了QAQ
#include
using namespace std;
int mp[1005][1005]; //保存地图
int v[1005][1005],a[1000005];
struct node{
int x,y;
}zb[1000005];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0},};
int main(){
int n,m,cnt;
cin >> n >> m;
char c;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
cin >> c;
if(c == '1') mp[i][j] = 1;
else mp[i][j] = 0;
}
}
int d = 0,f,r;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
if(v[i][j] == 0){
d++;
f = 1;
r = 1;
zb[f].x = i;
zb[f].y = j;
v[i][j] = d;
cnt = 1;
while(f <= r){
for(int k = 0;k < 4;k++){
int x1 = zb[f].x + dir[k][0];
int y1 = zb[f].y + dir[k][1];
if(v[x1][y1]== 0 && x1 >= 1 && y1 >= 1 && x1 <= n && y1 <= n
&& (( mp[x1][y1] == 1 && mp[zb[f].x][zb[f].y] == 0) ||
(mp[x1][y1] == 0 && mp[zb[f].x][zb[f].y] == 1)) ){
r++;
cnt++;
v[x1][y1] = d;
zb[r].x = x1;
zb[r].y = y1;
}
}
f++;
}
a[d] = cnt;
}
}
}
int sx,sy;
for(int i = 1;i <= m;i++){
cin >> sx >> sy;
cout << a[v[sx][sy]] << endl;
}
return 0;
}
单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母,要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次),在两个单词相连时,其重合部分合为一部分,例如 beastbeast和astonishastonish,如果接成一条龙则变为beastonishbeastonish,另外相邻的两部分不能存在包含关系,例如atat 和 atideatide 间不能相连。
输入的第一行为一个单独的整数n (n≤20)表示单词数,以下n 行每行有一个单词,输入的最后一行为一个单个字符,表示“龙”开头的字母。你可以假定以此字母开头的“龙”一定存在.
只需输出以此字母开头的最长的“龙”的长度
5
at
touch
cheat
choose
tact
a
23
样例(连成的“龙”为atoucheatactactouchoose)
NOIp2000提高组第三题
本来写的时候用了挺蠢的方法、、、然后连样例都不对
后来大佬点拨我说可以用数组存两个字符串的重叠部分的长度
#include
using namespace std;
string s[30];
int cd[30][30]; //计算i和j重叠部分的长度
int v[30];
int len = 0;
int ans = -1;
int n;
int func(int x,int y){
bool f = true;
int idx = 0;
for(int k = s[x].size()-1;k >= 0;k--){
for(int l = k;l < s[x].size();l++){
if(s[x][l] != s[y][idx++]){
f = false;
break;
}
}
if(f){
return s[x].size()-k;
}
idx = 0;
f = true;
}
return 0;
}
void dfs(int t){
bool flag = false;
for(int j = 1;j <= n;j++){
if(v[j] >= 2) continue; //使用超过两次
if(cd[t][j] == 0) continue; //不重叠
//两者包含
if(cd[t][j] == s[t].size() || cd[t][j] ==s[j].size()) continue;
len += s[j].size() - cd[t][j];
v[j]++;
flag = true;
dfs(j);
len -= s[j].size() - cd[t][j];
v[j]--;
}
if(!flag){
ans = max(ans,len);
}
return;
}
int main(){
cin >> n;
for(int i = 1;i <= n;i++){
cin >> s[i];
}
char c; cin >> c;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
//计算最小重叠部分
cd[i][j] = func(i,j);
}
}
for(int i = 1;i <= n;i++){
if(s[i][0] == c){
v[i]++;
len = s[i].size();
dfs(i);
v[i] = 0;
}
}
cout << ans << endl;
return 0;
}
There are NN light bulbs indexed from 0 to N−1. Initially, all of them are off.
A FLIP operation switches the state of a contiguous subset of bulbs. FLIP(L, R) means to flip all bulbs xx such that L≤x≤R. So for example,FLIP(3,5)FLIP(3,5) means to flip bulbs 33 , 44 and 55, and FLIP(5, 5)FLIP(5,5) means to flip bulb 55.
Given the value of NN and a sequence of M flips, count the number of light bulbs that will be on at the end state.
The first line of the input gives the number of test cases, T. T test cases follow. Each test case starts with a line containing two integers N and M, the number of light bulbs and the number of operations, respectively. Then, there are M more lines, the i-th of which contains the two integers Li and Ri,indicating that the i-th operation would like to flip all the bulbs from Li to Ri, inclusive.
1≤T≤1000
1≤N≤1e6
1≤M≤1000
0 ≤ Li ≤ Ri ≤ N−1
For each test case, output one line containing Case #x: y, where xx is the test case number (starting from 11) and yy is the number of light bulbs that will be on at the end state, as described above.
2
10 2
2 6
4 8
6 3
1 1
2 3
3 4
Case #1: 4
Case #2: 3
这道题卡死了一片人。。暴力法存普通数组tle了6ms,然后改了map结果超了内存。。。然后开始头铁
不停地莽交,甚至他们还妄图用玄学做法A这道题!!!然鹅并没有用,果然这道题就是为了卡我们这些暴力循环的小胖友的
最后其他的题目看了看都打算放弃惹。。然后不死心的map改hashmap再试一次继续t,然后改了快读变成了wa、、惊奇操作
最后!!!感恩吴某人过来和我讲了他的未尝试的思路!!!如此的清奇!!!本来只是trytry,结果就A了!我的天!
#include
using namespace std;
int mp[2005];
int main(){
int T;
scanf("%d",&T);
for(int i=1;i<=T;i++){
int n,m;
scanf("%d%d",&n,&m);
int wz = 0;
for(int j=0;j<m;j++){
int l,r;
scanf("%d%d",&l,&r);
mp[wz++] = l;
mp[wz++] = r+1;
}
sort(mp,mp+wz);
int sum = 0;
for(int j = 1;j < wz;j += 2){
sum += mp[j]-mp[j-1];
}
printf("Case #%d: %d\n",i,sum);
}
return 0;
}
开学一周, 似乎轻松了一些(并不),划划水的日子里。。也不知道自己在瞎忙些什么。。下周不可以这样了哦!!!
啊没有大佬带队的时候,就慌得一批,还好唐龙能C我,沈阳赛我们就写了一个水题,然后尝试写过的题都是别人通过率贼低,果然是选错题目了,我还以为都是签到题(明明是自己想的太过简单了)然后上海赛卡死B,也就是上面解析的那题。。。嘤嘤嘤,然后看别人签到了L,就去签了L,在放弃的边缘,终于A了。。。而且还是听了大佬的新思路,收回上周的话,暴力法未必天下第一…