A 挑战密室
化学方程式求分子量
这题我懒得写了
可以用map
之后,从头遍历到尾。
1.数字:连读直到不是数字
2.字母:连读直到不是字母
3.括号:从左括号开始遍历,重复1、2,到右括号退出
下面这个代码可以AC,但是有bug的,数字超过10,或者字母连着>3个就挂了
#include
#include
#include
B 最大岛屿
dfs统计连通分量模板
void dfs(int x,int y){
flood[x][y] = area;
for(int i=0;i<8;i++){
int tx = x + dr[i][0];
int ty = y + dr[i][1];
if(in(tx,ty) && a[tx][ty] == 1 && flood[tx][ty] == 0){
dfs(tx,ty);
}
}
}
主要注意地图的读写,中间有空格,可以用getchar读取
#include
using namespace std;
const int maxn = 510;
int m,n,t;
int a[maxn][maxn];
int area = 0;
int flood[maxn][maxn];
int dr[8][2] = {{0,1},{0,-1},{-1,0},{1,0},{1,-1},{-1,1},{-1,-1},{1,1}};
int s[maxn*maxn];
bool in(int x,int y){
return x>=1 && x<=n && y>=1 && y<=m;
}
void dfs(int x,int y){
flood[x][y] = area;
for(int i=0;i<8;i++){
int tx = x + dr[i][0];
int ty = y + dr[i][1];
if(in(tx,ty) && a[tx][ty] == 1 && flood[tx][ty] == 0){
dfs(tx,ty);
}
}
}
int main(){
cin>>n>>m>>t;
getchar();
char ch;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
while((ch = getchar()) == ' '){}
a[i][j] = ch - '0';
}
getchar();
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(flood[i][j] == 0 && a[i][j] == 1){
area++;
dfs(i,j);
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(flood[i][j] != 0){
s[flood[i][j]]++;
}
}
}
long long maxarea = 0;
for(int i=1;i<=area;i++){
if(s[i] > maxarea) maxarea = s[i];
}
cout<
C 最少换乘
写bfs搜索(求最短路)过的
首先把所有与起点1同一路线的点都入队(step表示换成次数 = 0)
bfs每次取出头部,搜索
当两点时同一公交路线时,新状态step不变
当两点不是同一公交路线时,新状态step+1
vis二维数组标记这条边是否走过
另外注意:这道题读入比较麻烦
没有告诉我们 每行有多少个数
我用getline函数来读的,getline(std::cin,string),读入到字符串string中
其他博客写的题解,用单源点最短路dijkstra做的 https://blog.csdn.net/dreamlandz/article/details/51509382
#include
using namespace std;
const int maxn = 510;
int g[maxn][maxn];
int t;
int n,m;
int a[maxn];
int vis[maxn][maxn];
struct edge{
int u;
int w;
edge(int uu = 0,int ww = 0){
u = uu;
w = ww;
}
};
vector v[maxn];
int sstation;
int estation;
struct node{
int xx;
int station;
int step;
node(int xxx,int stations,int steps){
xx = xxx;
station = stations;
step = steps;
}
};
int bfs(){
queue q;
// q.push(node(1,3,0)); //这里应该把和a相连的全部入队 就是下面几行
for(int i=0;i>t;
while(t--){
memset(vis,0,sizeof(vis));
cin>>m>>n;
getchar();
for(int i=1;i<=m;i++){
string temp;
getline(std::cin, temp);
int len = 0;
for(int j=0;j
D 引水工程
最小生成树,prim和kru...都可以过
kru最小生成树
建图时 自己对自己也算一条边(如果要选条边,不能算n-1条边里)
#include
using namespace std;
/*
想法1:
kru最小生成树
建图时 自己对自己也算一条边(如果要选条边,不能算n-1条边里)
*/
/*
想法2:从权值最小的开始建水库 prim算法
*/
//kru做法
int n,m,minn,father[305],sum,tem[305];
struct node
{
int x,y,l;
}a[90005];
bool cmp(node a,node b)
{
return a.lsum2)
father[y]=x;
else
father[x]=y;
return true;
}
else
return false;
}
int main() // 先用 Dijkstra 做一次 // Dijkstra 是 根据边来做的
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<=n;i++)
father[i]=i;
int q=0;
//i从0开始 多输了一次
for(int i=0;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int e;
scanf("%d",&e);
a[q].x=j;
a[q].y=i;
a[q].l=e;
q++;
}
}
int sum3=0,count1=0;
sort(a,a+q,cmp);
for(int i=0;i
Prim求最小生成树
在选择最小邻接边时,和顶点再比较一下
#include
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 510;
bool vis[maxn];
int dist[maxn];
int g[maxn][maxn];
int a[maxn];
int n,t;
//想法2:从权值最小的开始建水库 prim算法
//有水可以自身引水 或者其它地区引水 所以如果 最小的邻接边的费用 比对应顶点的权值大 就自己引水
int Prim(int pos){
int ans = 0;
memset(vis,false,sizeof(vis));
ans = a[pos];
vis[pos] = true;
for(int i=1;i<=n;i++) dist[i] = g[pos][i];
for(int i=1;i<=n-1;i++){
int minc = inf;
int p = -1;
for(int j=1;j<=n;j++){
if(!vis[j] && minc > dist[j]){
minc = dist[j];
p = j;
}
}
//应题目中的要求(每个点都要有水)
//有水可以自身引水 或者其它地区引水 所以如果 最小的邻接边的费用 比对应顶点的权值大 就自己引水
if(minc > a[p]){
ans += a[p];
vis[p] = true;
continue;
}
vis[p] = true;
ans += dist[p];
for(int j=1;j<=n;j++){
if(!vis[j] && dist[j] > g[p][j]){
dist[j] = g[p][j];
}
}
}
return ans;
}
int main(){
cin>>t;
while(t--){
cin>>n;
int minv = inf;
int pos = 1;
for(int i=1;i<=n;i++){
cin>>a[i];
if(a[i] < minv){
minv = a[i];
pos = i;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>g[i][j];
}
}
cout<
F Distribution
校赛也出了这一道题,比较简单
给定两条线,求一三象限 与 二四象限 上的 点数差
#include
using namespace std;
const int maxn = 1100;
int n,m;
int g[maxn][maxn]; // 0开始(0也算)
int maxx = 0;
int maxy = 0;
int solve(int x,int y){
int sum = 0;
for(int i=0;i>n>>m;
for(int i=1;i<=n;i++){
int xi,yi;
cin>>xi>>yi;
g[xi][yi] = 1;
if(xi > maxx) maxx = xi;
if(yi > maxy) maxy = yi;
}
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
int ans1 = 0;
int ans2 = 0;
ans1 = solve(x,y);
ans2 = n - ans1;
cout<
G Interference Signal
题意:给定n个数,求最大的 至少连续m个数的平均值
枚举起点,算平均值就可以了
#include
using namespace std;
const int maxn = 2050;
int t;
int a[maxn];
int sum[maxn];
int n,m;
int main(){
cin>>t;
while(t--){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i] = a[i] * 1000;
}
memset(sum,0,sizeof(sum));
sum[0] = 0;
for(int i=1;i<=n;i++){
sum[i] = sum[i-1] + a[i];
}
double average = 0;
for(int i=1;i<=n;i++){
for(int j=i+m-1;j<=n;j++){
double avetemp = (sum[j] - sum[i-1])*1.0/ (j-i+1);
if(avetemp > average) average = avetemp;
}
}
int ans = average;
printf("%d\n",ans);
}
return 0;
}