目录
第10周-图(1) A B C K
//A
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
using namespace std;
#define LL long long
#define M(a,b) memset(a,b,sizeof(a))
const int MAXN = 1e3+5;
const int INF = 0x3f3f3f3f;
int X[5] = {0,0,0,-1,1};
int Y[5] = {0,1,-1,0,0};
queue<pair<int,int> >q;
int vis1[MAXN][MAXN];
int vis2[MAXN][MAXN];
int MAP[MAXN][MAXN];
vector<pair<int,int> >v;///存储所有着火点
int jx,jy;
int r,c;
void bfs1()///算出火势蔓延到所有格子的时间
{
for(int i=0; i<v.size(); i++)
{
q.push(make_pair(v[i].first,v[i].second));
vis1[v[i].first][v[i].second] = 1;
}
while(!q.empty())
{
int x1 = q.front().first;
int y1 = q.front().second;
q.pop();
for(int i=1; i<=4; i++)
{
int xx = x1 +X[i];
int yy = y1 +Y[i];
if(xx>=1&&xx<=r&&yy>=1&&yy<=c&&vis1[xx][yy]==0&&MAP[xx][yy]!=-1)
{
vis1[xx][yy] = vis1[x1][y1]+1;
q.push(make_pair(xx,yy));
}
}
}
}
int bfs2(int x,int y)///计算出这个人到达所有格子的时间
{
while(!q.empty()) q.pop();
q.push(make_pair(x,y));
vis2[x][y] = 1;
while(!q.empty())
{
int x1 = q.front().first;
int y1 = q.front().second;
if((x1==1||x1==r||y1==1||y1==c))///到达边界时,逃脱成功
{
return vis2[x1][y1];
}
q.pop();
for(int i=1; i<=4; i++)
{
int xx = x1 +X[i];
int yy = y1 +Y[i];
if(xx>=1&&xx<=r&&yy>=1&&yy<=c&&vis2[xx][yy]==0&&MAP[xx][yy]!=-1)
{
vis2[xx][yy] = vis2[x1][y1]+1;
if(vis2[xx][yy]>=vis1[xx][yy]&&vis1[xx][yy]!=0) ///人到达该格子的时间要早于火到达的,且是火能到达的。
continue;
q.push(make_pair(xx,yy));
}
}
}
return -1;
}
void init()
{
M(vis2,0);
M(vis1,0);
v.clear();
while(!q.empty()) q.pop();
}
int main()
{
int T;
cin>>T;
while(T--)
{
init();
scanf("%d %d",&r,&c);
for(int i=1; i<=r; i++)
{
for(int j=1; j<=c; j++)
{
char temp;
cin>>temp;
if(temp=='#') MAP[i][j] = -1;
if(temp=='.') MAP[i][j] = 1;
if(temp=='F')
{
v.push_back(make_pair(i,j));///着火点不唯一
}
if(temp=='J')
{
jx = i;
jy = j;
}
}
}
bfs1();
int ans = bfs2(jx,jy);
if(ans==-1)
{
printf("IMPOSSIBLE\n");
}
else
{
printf("%d\n",ans);
}
}
return 0;
}
//2
//3 4
//F#..
//#J..
//....
//B
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
char mp[35][35];
int book[35][35][4][5];
int to[4][2]= {-1,0,0,1,1,0,0,-1};//按照 上、右、下、左的方向。
int m,n;
int sx,sy,ex,ey;
struct note
{
int x,y,d,c,time;
} t,head,tnext;
queue<note> q;
//0,1,2,3 上、右、下、左
//0,1,2,3,4 //0表示绿色,我们只用到绿色
int bfs()
{
t.x=sx,t.y=sy,t.d=0,t.c=0,t.time=0;
book[sx][sy][0][0]=1;
q.push(t);
while(!q.empty())
{
head=q.front();
if(head.x==ex&&head.y==ey&&head.c==0)
return head.time;
q.pop();
//顺时针旋转
tnext.x=head.x;
tnext.y=head.y;
tnext.c=head.c;
tnext.d=(head.d+1)%4;
tnext.time=head.time+1;
if(book[tnext.x][tnext.y][tnext.d][tnext.c]==0)
{
book[tnext.x][tnext.y][tnext.d][tnext.c]=1;
q.push(tnext);
}
//逆时针旋转
tnext.x=head.x;
tnext.y=head.y;
tnext.c=head.c;
tnext.d=(head.d+3)%4;
tnext.time=head.time+1;
if(book[tnext.x][tnext.y][tnext.d][tnext.c]==0)
{
book[tnext.x][tnext.y][tnext.d][tnext.c]=1;
q.push(tnext);
}
//开始走
tnext.x=head.x+to[head.d][0];
tnext.y=head.y+to[head.d][1];
tnext.c=(head.c+1)%5;
tnext.d=head.d;
tnext.time=head.time+1;
if(mp[tnext.x][tnext.y]=='#')
continue;
if(book[tnext.x][tnext.y][tnext.d][tnext.c]==1)
continue;
if(tnext.x<0||tnext.x>=m||tnext.y<0||tnext.y>=n)
continue;
book[tnext.x][tnext.y][tnext.d][tnext.c]=1;
q.push(tnext);
}
return 0;
}
int main()
{
int ans=0;
while(~scanf("%d%d",&m,&n)&&m&&n)
{
ans++;
while(!q.empty())
q.pop();
memset(book,0,sizeof(book));
int i,j,k;
for(i=0; i<m; i++)
scanf("%s",mp[i]);
for(i=0; i<m; i++)
{
for(j=0; j<n; j++)
{
if(mp[i][j]=='S')
sx=i,sy=j;
if(mp[i][j]=='T')
ex=i,ey=j;
}
}
int minn=bfs();
if(ans>1)
printf("\n");
if(minn)
printf("Case #%d\nminimum time = %d sec\n",ans,minn);
else
printf("Case #%d\ndestination not reachable\n",ans);
}
return 0;
}
//C
//#include"bits/stdc++.h"
//#include<unordered_map>
//#include<unordered_set>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
#include<vector>
#include<bitset>
#include<climits>
#include<queue>
#include<iomanip>
#include<cmath>
#include<stack>
#include<map>
#include<ctime>
#include<new>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define MT(a,b) memset(a,b,sizeof(a))
#define lson l, mid, node << 1
#define rson mid + 1, r, node << 1 | 1
const int INF = 0x3f3f3f3f;
const int O = 1e5;
const int mod = 1e4 + 7;
const int maxn = 1e3+5;
const double PI = acos(-1.0);
const double E = 2.718281828459;
int f[maxn];
int col[maxn];
int way[51][51];
int n;
void init(){
MT(way, 0);
for(int i=1; i<=50; i++){
f[i] = i; col[i] = 0;
}
}
int find(int x){
return x == f[x] ? x : f[x] = find(f[x]);
}
void Union(int u, int v){
if((u=find(u))!=(v=find(v))){
f[u] = f[v];
}
}
void Oular(int u){ // 欧拉回路模板
for(int v=1; v<=50; v++) {
if(way[u][v]) {
way[u][v] -- ; way[v][u] -- ;
Oular(v);
printf("%d %d\n", v, u);
}
}
}
bool check(){ // 如果存在度为奇数,返回false, 如果不是连通图,返回false
int front = 0; //记录遍历的上一个节点
for(int i=1; i<=50; i++) {
if(col[i] & 1) return false;
if(!front && col[i]) {front = i; continue;}
if(col[i] && find(i) != find(front)) return false;
}
return true;
}
int main(){
int T, ca = 0; scanf("%d", &T);
while(T --) {
init(); scanf("%d", &n);
int st = 0; //起点
for(int i=0; i<n; i++) {
int u, v; scanf("%d%d", &u, &v);
if(!st) st = u;
way[u][v] ++; way[v][u] ++; // 记录每条边的的个数
col[u] ++; col[v] ++; // 记录每个节度的个数
Union(u, v);
}
printf("Case #%d\n", ++ca);
if(!check()) { // 判断是否存在欧拉回路
printf("some beads may be lost\n");
goto loop;
}
Oular(st);
loop:if( T ) printf("\n");
}
return 0;
}
//K#include<stdio.h>
#include<iostream>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 10002
int V;
vector <int>G[maxn];
int color[maxn];
bool dfs(int v,int c)
{
color[v]=c;
for(int i=0;i<G[v].size();i++)
{
if(color[G[v][i]]==c)return false;
if(color[G[v][i]]==0&&!dfs(G[v][i],-c))return false;
}
return true;
}
void solve()
{
for(int i=0;i<V;i++)
{
if(color[i]==0)
if(!dfs(i,1))
{
printf("NO\n");
return;
}
}
printf("YES\n");
}
int main()
{
int s,t;
while(scanf("%d",&V)&&V)
{
memset(color,0,sizeof(color));
for(int i=0;i<maxn;i++)
G[i].clear();
while(scanf("%d%d",&s,&t))
{
if(!s && !t)break;
G[s].push_back(t);
G[t].push_back(s);
}
solve();
}
}
第10周-图(4)-基础题 D H
//D
#include<iostream>
#include<queue>
#include<stdio.h>
#include<string.h>
#define N 100
using namespace std;
int r,c,ans;
char mp[N][N];
bool vis[N][N];
int fx[8]={1,0,-1,0,-1,1,-1,1};
int fy[8]={0,1,0,-1,-1,-1,1,1};
struct node
{
int x,y;
};
bool check(int x,int y)
{
if(!vis[x][y] && mp[x][y]=='@' && x>=0 && x<r && y>=0 && y<c )
return 1;
return 0;
}
void bfs(int x,int y)
{
queue<node> q;
q.push({x,y});
while(q.size())
{
node now=q.front();
q.pop();
for(int i=0;i<8;i++)
{
int nextx=now.x + fx[i];
int nexty=now.y + fy[i];
if(check(nextx,nexty))
{
vis[nextx][nexty]=1;
q.push({nextx,nexty});
}
}
}
return ;
}
int main()
{
ios_base::sync_with_stdio;
while(cin>>r>>c && r)
{
ans=0;
memset(vis,0,sizeof vis);
memset(mp,0,sizeof mp);
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
cin>>mp[i][j];
}
}
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
if(mp[i][j]=='@' && !vis[i][j])
{
bfs(i,j);
ans++;
}
}
}
cout<<ans<<endl;
}
return 0;
}
//H C语言
#include<stdio.h>
#include<string.h>
int s[301][301];
int vis[301][301];
int step[301][301];
int f[16]={-1,-2,-2,-1, 1,2,2,1, -2,-1,1,2, 2,1,-1,-2};
struct node
{
int x;
int y;
}q[100000];
int main()
{
int front,rear,t,i,j,n,x0,y0,x1,y1;
scanf("%d",&t);
while(t--)
{
memset(vis,0,sizeof(vis));
memset(step,0,sizeof(step));
scanf("%d%d%d%d%d",&n,&x0,&y0,&x1,&y1);
front=0;
rear=0;
q[rear].x=x0;
q[rear++].y=y0;
step[x0][y0]=0;
vis[x0][y0]=1;
while(front<rear)
{
for(i=0;i<8;i++)
if(!vis[q[front].x+f[i]][q[front].y+f[i+8]]&&q[front].x+f[i]>=0&&q[front].x+f[i]<n&&q[front].y+f[i+8]>=0&&q[front].y+f[i+8]<n)
{
q[rear].x=q[front].x+f[i];
q[rear++].y=q[front].y+f[i+8];
vis[q[front].x+f[i]][q[front].y+f[i+8]]=1;
step[q[front].x+f[i]][q[front].y+f[i+8]]=step[q[front].x][q[front].y]+1;
if(vis[x1][y1])
break;
}
front++;
if(vis[x1][y1])
break;
}
printf("%d\n",step[x1][y1]);
}
return 0;
}
第10周-图(5)-图的建立 A B
//A
#include<stack>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1005
#define M 1000005
using namespace std;
int n,m,t,ans=1;
int a[N],f[N],du[N];
int v[M],next[M],first[N];
bool used[N],have[N][N];
stack<int>sta;
void add(int x,int y)
{
t++;
next[t]=first[x];
first[x]=t;
v[t]=y;
}
void link(int x,int s)
{
int i;
for(i=1;i<=s;++i)
{
if(!have[x][a[i]])
{
add(x,a[i]);
du[a[i]]++;
have[x][a[i]]=true;
}
}
}
void topology()
{
int x,i;
for(i=1;i<=n;++i)
if(!du[i])
f[i]=1,sta.push(i);
while(!sta.empty())
{
x=sta.top();
sta.pop();
for(i=first[x];i;i=next[i])
{
f[v[i]]=max(f[v[i]],f[x]+1);
ans=max(ans,f[v[i]]),--du[v[i]];
if(!du[v[i]]) sta.push(v[i]);
}
}
}
int main()
{
int s,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=m;++i)
{
scanf("%d",&s);
memset(used,false,sizeof(used));
for(j=1;j<=s;++j)
{
scanf("%d",&a[j]);
used[a[j]]=true;
}
for(j=a[1];j<=a[s];++j)
if(!used[j])
link(j,s);
}
topology();
printf("%d",ans);
return 0;
}
//B
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,s,a[2001],b[2001],c[2001];
bool judge(int *A,int *B)
{
for (int i=1; i<=n; i++)
if (A[i]!=B[i]) return false;
return true;
}
int main()
{
scanf("%d%d",&n,&s);
for (int i=1; i<=n; i++) scanf("%d",&a[i]),b[i]=a[i];
int total=0;//循环节的长度
while (1)
{
for (int i=1; i<=n; i++)
c[i]=b[b[i]];
total++;
if (judge(c,a)) break;
for (int i=1; i<=n; i++)
b[i]=c[c[i]];
total++;
if (judge(b,a)) break;
}
total=total-s%total;//num向后数几个 必须要%%%%!
int k=0;
for (int i=1; i<=n; i++) b[i]=a[i];//漏掉了这里
while (1)
{
for (int i=1; i<=n; i++) c[i]=b[b[i]];
k++;
if (k==total)
{
for (int i=1; i<=n; i++) printf("%d ",c[i]);
return 0;
}
for (int i=1; i<=n; i++) b[i]=c[c[i]];
k++;
if (k==total)
{
for (int i=1; i<=n; i++) printf("%d ",b[i]);
return 0;
}
}
return 0;
}
/*
5 2
4 1 5 3 2
2 5 4 1 3
*/
第8-9周-搜索(2)-来自洛谷 A B C E
//A
#include<bits/stdc++.h>
using namespace std;
char str[10][10][5];
int n,f[300];//f为map
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%s",str[i][j]);
for(int i=2;i<=n;i++)
for(int j=2;j<=n;j++)
if(strlen(str[i][j])==1)
f[str[i][j][0]]++;
for(int i=2;i<=n;i++){
for(int j=2;j<=n;j++){
int x=f[str[i][1][0]]-1,y=f[str[1][j][0]]-1;
int sum=0,t;
for(int k=0;k<strlen(str[i][j]);k++){
t=f[str[i][j][k]]-1;
sum=sum*(n-1)+t;//进制转换
}
if(x+y!=sum){//不合法
printf("ERROR!");
return 0;
}
}
}
for(int i=2;i<=n;i++){
printf("%c=%d ",str[1][i][0],f[str[1][i][0]]-1);//空格忘记加了搞了好久(我直接在网站里打代码,不编译)
}
printf("\n%d",n-1);
return 0;
}
//B
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 21;
int n;
string word[N];
int g[N][N];//两个单词重合部分最小长度
int used[N];//单词使用次数
int ans;
string d;
void dfs(string dragon, int last) //last表示结尾用的单词
{
if(dragon.size() > ans){
ans = dragon.size();
d=dragon;
}
used[last] ++ ;
for (int i = 0; i < n; i ++ )
if (g[last][i] != 0 && used[i] < 2){
dfs(dragon + word[i].substr(g[last][i]), i);
used[last] -- ; //回溯减一
}
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ ) cin >> word[i];
char start;
cin >> start;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
{
string a = word[i], b = word[j];
//重合部分的长度,但其长度必须大于等于1,且严格小于两个串的长度
for (int k = 1; k < min(a.size(), b.size()); k ++ )
if (a.substr(a.size() - k, k) == b.substr(0, k))
{
g[i][j] = k;
break;
}
}
for (int i = 0; i < n; i ++ )
if (word[i][0] == start)
dfs(word[i], i);
cout << ans << endl;
return 0;
}
//C
#include <iostream>
#include <algorithm>
using namespace std;
#define inf 1145141919
#define MAXLEN 19
int value[MAXLEN];
int n, k;
int mmax = 0;
int result[MAXLEN];
int dp[MAXLEN*MAXLEN];
void dfs(int x)
{
if(x == k)
{
// 最大的能够拼凑的价值是n张最大的邮票的价值
int maxlen = n*value[k-1];
dp[0] = 0;
dp[1] = 1;
int i;
for(i=2; i<=maxlen; i++)
{
int min = inf;
for(int j=0; j<k; j++)
{
if(i-value[j] >= 0)
{
if(dp[i-value[j]]+1 < min)
{
min = dp[i-value[j]] + 1;
}
}
}
dp[i] = min;
// 如果找到第一个不能拼凑出的值
if(dp[i] > n)
{
break;
}
}
// 保存面值的结果
if(i > mmax)
{
mmax = i;
for(int j=0; j<k; j++)
{
result[j] = value[j];
}
}
}
else
{
// 第i张邮票的面值不能超过n*【第i-1张邮票的面值】+1
for(int i=value[x-1]+1; i<=value[x-1]*n+1; i++)
{
value[x] = i;
dfs(x+1);
}
}
}
int main()
{
cin>>n>>k;
value[0] = 1;
dfs(1);
for(int i=0; i<k; i++)
{
cout<<result[i]<<" ";
}
cout<<endl<<"MAX="<<mmax-1<<endl;
return 0;
}
//E
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
string a, b;
void before( int hl, int hr,int zl, int zr)
{
if (zl == zr) {
return;
}
int flag=-1;
for (int i = 0; i < zr; i++) {
if (a[i] == b[hr - 1]) {
flag = i;
cout << a[flag];
break;
}
}
before( hl, hl + flag- zl,zl, flag); //左子树
before(hl+ flag - zl, hr - 1,flag + 1, zr); //右子树
}
int main()
{
cin >> a >> b;
before( 0, b.length(),0, a.length());
}