【A】水题,模拟即可。
【B】水题,判断给定的图是否有环存在?dfs记录当前位置和从哪个方向来的即可!
const int dir[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
char maze[55][55];
bool vis[55][55];
int n,m,ok;
void dfs(int x,int y,int px,int py)
{
if(vis[x][y]){
ok = 1;
return ;
}
vis[x][y] = 1;
for(int i = 0; i < 4; i++){
int dx = x + dir[i][0];
int dy = y + dir[i][1];
if(dx < 0 || dx >= n || dy < 0 || dy >= m) continue;
if(dx == px && dy == py) continue ;
if(maze[dx][dy] == maze[x][y])
{
dfs(dx,dy,x,y);
}
}
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
ok = 0;
for(int i = 0; i < n; i++) scanf("%s",maze[i]);
memset(vis, false, sizeof(vis));
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(!vis[i][j]){
dfs(i,j,i,j);
if(ok) break;
}
}
if(ok) break;
}
if(ok) puts("Yes");
else puts("No");
}
}
【C】要你确定26小写字母的排列顺序,使得给定的字符串是按照这个字母表,按照字典序从小到大。容易瞧出来,这实际上就是一个有向图的拓扑序。复杂度O(n)
const int maxn = 111;
int in[maxn],ans[maxn],n;
char s[maxn][maxn];
vector<int>g[maxn];
queue<int>q;
void topsort()
{
memset(ans, 0, sizeof(ans));
while(!q.empty()) q.pop();
for(int i = 0; i < 26; i++){
if(!in[i]) q.push(i);
}
int num = 0;
while(!q.empty())
{
int u = q.front();
q.pop();
ans[num++] = u;
for(int i = 0; i < g[u].size(); i++){
int v = g[u][i];
--in[v];
if(!in[v]){
q.push(v);
}
}
}
//cout<<num<<endl;
if(num < 26)
{
puts("Impossible\n");
return ;
}
for(int i = 0; i < num; i++) printf("%c", ans[i] + 'a');
printf("\n");
}
int main()
{
while(scanf("%d", &n)!=EOF){
memset(in, 0, sizeof(in));
for(int i = 1; i <= n; i++) g[i].clear();
for(int i = 0; i < n; i++) scanf("%s",s[i]);
bool ok = 0;
for(int i = 1; i < n; i++)
{
int len1 = strlen(s[i-1]);
int len2 = strlen(s[i]);
int a = 0,b = 0;
while(a < len1 && b < len2 && s[i-1][a] == s[i][b])
{
a++;
b++;
}
if(b == len2 && a < len1)
{
ok = 1;
break;
}
if(a == len1 && b <= len2) continue;
in[s[i][b]-'a']++;
g[s[i-1][a]-'a'].push_back(s[i][b]-'a');
}
if(ok)
{
puts("Impossible");
}
else
{
topsort();
}
}
}
【D】给了一列数,每个数有个价值,要你找到一些数使得这些数可以组成数轴上的所有数。实际上就是让这些数的最大公约数为1即可,然后找这些集合的最小值。map+dp思想就可以了。mp[i]公约数为i的最小价值,暴力去更新就可以了,复杂度O(n*n)。
const int maxn = 333;
LL l[maxn],c[maxn];
map<LL,LL>mp;
int n;
int main()
{
while(scanf("%d",&n) != EOF)
{
mp.clear();
for(int i = 1; i <= n; i++) scanf("%lld",&l[i]);
for(int i = 1; i <= n; i++) scanf("%lld",&c[i]);
mp[0] = 0;
for(int i = 1; i <= n; i++){
for(map<LL,LL>::iterator it = mp.begin(); it != mp.end(); it++){
LL v = it->first;
LL x = __gcd(v, l[i]);
if(mp.find(x)!=mp.end()) mp[x] = min(mp[x], it->second + c[i]);
else mp[x] = it->second + c[i];
}
}
if(!mp[1]) printf("-1\n");
else{
printf("%lld\n",mp[1]);
}
}
}
【E】网络流,留坑。