要有一定刷题量
若想在省赛中取得较好成绩,建议做200题左右。
若想在国赛中取得较好成绩,建议做300题左右。
本课程约讲解100题左右。
要重视调试
有思路得前提下,若调试不过,不要立马问别人。要自己努力解决问题。
要重视考试。
感受真实氛围,检验学习成果。
比赛时比的并不是去发明或者去创造某一个思路,比赛比的是熟练度。
算法题特点:
1、与数学、物理等学科相比,算法题的模型相对较少。
2、思维量高
3、编写编程能力 。要用理论去指导实践。数学题想出来就能做出来,但是算法题能想出来不一定能实现出来。
做题过程
1、看题目描述
2、分析,抽象出来它考什么模型。分析出题人是想问什么。
3、回忆之前学过的算法或做过的题目能不能解决这个问题。若不能,再去回溯。解决方案是平时多去积累一些题目,多去刷一些题目。只有平时积累的多了,考试的时候才能学以致用。
如何判断一个算法能不能用?
1、首先看正确性
2、再看时间是否超限制。
C++ 评测机一秒约运行一亿次。若算法的的时间复杂度超过108,则可能会超时。
做题时,先看数据范围,排除不能使用的算法。找到题目数据范围区间之内的算法。这样做题思路会更明确。
数据范围可以带给我们非常多的信息。
学算法一定要落实到代码上
若输入输出 范围 小于 105 推荐用 cin / cout 否则用 scanf / printf 输入时间会快一倍左右。
递归计算斐波那契数列
#include
using namespace std;
int f(int n )
{
if (n == 1) return 1;
if (n == 2) return 2;
return f(n - 1) + f(n - 2);
}
int main()
{
int n ;
cin >> n;
cout << f(n);
return 0;
}
#include
#include
#include
#include
using namespace std;
const int N = 16;
int n;
int st[N];//状态,记录每个位置当前的状态:0表示还没考虑,1表示选它,2表示不选它。
void dfs(int u)
{
if (u > n)
{
for (int i =1; i <= n; i ++ )
if (st[i] == 1)
printf("%d ", i);
printf("\n");
return;
}
st[u] = 2;
dfs(u + 1); //第一个分支: 不选
st[u] = 0; //恢复现场
st[u] = 1;
dfs(u + 1); // 第二个分支: 选
st[u] = 0;
}
int main()
{
cin >> n;
dfs(1);
return 0;
}
变形 :如何输出所有方案?
#include
#include
#include
#include
#include
using namespace std;
const int N = 16;
int n;
int st[N];//状态,记录每个位置当前的状态:0表示还没考虑,1表示选它,2表示不选它。
vector<vector<int>> ways;
void dfs(int u)
{
if (u > n)
{
vector<int> way;
for (int i = 1; i <= n; i ++ ) // 记录方案
if (st[i] == 1)
way.push_back(i);
ways.push_back(way);
return;
}
st[u] = 2;
dfs(u + 1); //第一个分支: 不选
st[u] = 0; //恢复现场
st[u] = 1;
dfs(u + 1); // 第二个分支: 选
st[u] = 0;
}
int main()
{
cin >> n;
dfs(1);
for (int i = 0; i < ways.size(); i ++ )
{
for (int j = 0; j < ways[i].size(); j ++) printf("%d ", ways[i][j]);
puts(""); // puts是输出一个字符串,但是这个字符串为空,仅有一个回车。
//相当于printf("\n"); puts("")等价于只输出回车。
}
return 0;
}
#include
#include
#include
#include
using namespace std;
const int N = 10;
int n;
int state[N]; // 0表示还没放数,1~n表示放了哪个数
bool used[N]; // true表示用过,false表示还未用过
void dfs(int u)
{
if (u > n)
{
for (int i = 1; i <= n; i ++ )
cout << state[i] << ' ';
cout << endl;
return;
}
for (int i = 1; i <= n; i ++)
if (!used[i])
{
state[u] = i;
used[i] = true;
dfs(u + 1);
state[u] = 0;
used[i] = false;
}
}
int main()
{
cin >> n;
dfs(1);
return 0;
}
#include
#include
#include
#include
using namespace std;
const int N = 30;
int n, m;
int way[N];
void dfs(int u, int start)
{
if (n + u - start < m) return; // 如果把后面所以的数都选上还不够m个 当前分支无解。
if (u == m + 1)
{
for (int i = 1; i <= m ; i ++) printf("%d ", way[i]);
puts("");
return;
}
for (int i = start; i <= n; i ++)
{
way[u] = i;
dfs(u + 1, i + 1);
way[u] = 0;
}
}
int main()
{
scanf("%d%d", &n, &m);
dfs(1, 1);
return 0;
}
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int n ,m;
int q[N];
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++) cin >> q[i];
for (int i = 0; i < m; i ++)
{
int x;
cin >> x;
int l = 0, r = n - 1;
while (l < r)
{
int mid = l + r >> 1;
if (q[mid] >= x) r = mid;
else l = mid + 1;
}
if (q[r] == x) // 比较的是数组里的元素
{
cout << r << ' ';
r = n - 1;
while (l < r)
{
int mid = l + r + 1 >> 1;
if (q[mid] <= x) l = mid; //**这里写mid是不对的,要写[mid]
else r = mid - 1;
}
cout << l << endl;
}
else cout << "-1 -1" << endl;
}
return 0;
}
#include
#include
#include
using namespace std;
int main()
{
double x;
cin >> x;
double l = -100000, r = 100000;
while (r - l > 1e-8)
{
double mid = (l + r) / 2;
if (mid * mid * mid >= x) r = mid;
else l = mid;
}
printf("%.6lf", l);
return 0;
}
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int n, m;
int a[N];
int s[N];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++)
{
cin >> a[i];
s[i] = s[i - 1] + a[i];
}
while (m --)
{
int l, r;
cin >> l >> r;
cout << s[r] - s[l - 1] << endl;
}
return 0;
}
#include
#include
#include
using namespace std;
const int N = 1010;
int n, m, q;
int a[N][N], s[N][N];
int main()
{
cin >> n >> m >> q;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
{
cin >> a[i][j];
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];//++-+
}
while (q --)
{
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
cout << s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1] << endl;//+--+
}
return 0;
}
#include
using namespace std;
const int N = 10010;
int n, m, q;
int a[N][N];
int s[N][N];
int main()
{
cin >> n >> m >> q;
for (int i = 1; i <= n ; i++)
for (int j = 1; j <= m; j ++)
{
cin >> a[i][j];
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
}
while (q --)
{
int x1, y1, x2, y2;
cin >> x1 >> y1 >> x2 >> y2;
cout << s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1] << endl;
}
return 0;
}
#include
using namespace std;
int main()
{
int n,a,b,c,d;
scanf("%d",&n);
int sqn = int(sqrt(n));
for(a=0;a<=sqn;++a)
{
for(b=a;b<=sqn;++b)
{
for(c=b;c<=sqn;++c)
{
d=sqrt(n-a*a-b*b-c*c); //这里可以有效地减少一重循环
if(n==a*a+b*b+c*c+d*d)
{
if(c>d)swap(d,c);
printf("%d %d %d %d\n",a,b,c,d);
return 0;
}
}
}
}
}
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100010;
int n, k;
LL s[N];
int cnt[N];
int main()
{
cin >> n >> k;
for (int i = 1; i <= n; i ++)
{
cin >> s[i];
s[i] += s[i - 1];
}
LL res = 0;
cnt[0]++;
for (int i = 1; i <= n; i ++)
{
res += cnt[s[i] % k];
cnt[s[i] % k] ++;
}
cout << res;
return 0;
}
#include
#include
#include
using namespace std;
const int N = 10010, INF = 100000000;
int n;
int a[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ ) cin >> a[i];
int res = 0;
for (int i = 0; i < n; i ++ ) // 枚举区间左端点
{
int minv = INF, maxv = -INF;
for (int j = i; j < n; j ++ ) // 枚举区间右端点
{
minv = min(minv, a[j]);
maxv = max(maxv, a[j]);
if (maxv - minv == j - i) res ++ ;
}
}
cout << res << endl;
return 0;
}
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100010;
int n;
int a[N], b[N], c[N];
int as[N]; // as[i]表示在A[]中有多少个数小于b[i]
int cs[N]; // cs[i]表示在C[]中有多少个数大于b[i]
int cnt[N], s[N];
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]), a[i] ++ ;
for (int i = 0; i < n; i ++ ) scanf("%d", &b[i]), b[i] ++ ;
for (int i = 0; i < n; i ++ ) scanf("%d", &c[i]), c[i] ++ ;
// 求as[]
for (int i = 0; i < n; i ++ ) cnt[a[i]] ++ ;
for (int i = 1; i < N; i ++ ) s[i] = s[i - 1] + cnt[i]; // 求cnt[]的前缀和
for (int i = 0; i < n; i ++ ) as[i] = s[b[i] - 1];
// 求cs[]
memset(cnt, 0, sizeof cnt);
memset(s, 0, sizeof s);
for (int i = 0; i < n; i ++ ) cnt[c[i]] ++ ;
for (int i = 1; i < N; i ++ ) s[i] = s[i - 1] + cnt[i];
for (int i = 0; i < n; i ++ ) cs[i] = s[N - 1] - s[b[i]];
// 枚举每个b[i]
LL res = 0;
for (int i = 0; i < n; i ++ ) res += (LL)as[i] * cs[i];
cout << res << endl;
return 0;
}
//暴力做法 通过了6/12 个数据
#include
using namespace std;
const int N = 100010;
int a[N], b[N], c[N];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i ++) cin >> a[i];
for (int i = 0; i < n; i ++) cin >> b[i];
for (int i = 0; i < n; i ++) cin >> c[i];
int cnt = 0;
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
for (int k = 0; k < n; k ++)
if (a[i] < b[j] && b[j] < c[k])
cnt ++;
cout << cnt << endl;
return 0;
}
// int -> string
string get(int x)
{
string res;
int t = x % 10;
x /= 10;
res += t;
return res
}
// string -> int
int uget(string s)
{
int res = 0;
for (int i = 0; i < s.size(); i ++)
res = res * 10 + s[i] - '0';
return res;
}
#include
#include
using namespace std;
int main()
{
int n;
cin >> n;
int res = 0;
for (int i = 1; i <= n; i ++ )
{
int x = i;
while (x)
{
int t = x % 10; // 取出x的个位
x /= 10; // 删掉x的个位
if (t == 2 || t == 0 || t == 1 || t == 9)
{
res += i;
break;
}
}
}
cout << res << endl;
return 0;
}
#include
#include
#include
#include
using namespace std;
const int N = 10010;
int n;
int a[N];
int main()
{
int cnt;
cin >> cnt;
string line;
getline(cin, line); // 忽略掉第一行的回车 **
while (cnt -- )
{
getline(cin, line);
stringstream ssin(line);
while (ssin >> a[n]) n ++ ;
}
sort(a, a + n);
int res1, res2;
for (int i = 1; i < n; i ++ )
if (a[i] == a[i - 1]) res2 = a[i]; // 重号
else if (a[i] >= a[i - 1] + 2) res1 = a[i] - 1; // 断号
cout << res1 << ' ' << res2 << endl;
return 0;
}
//求四位回文数的程序
#include
using namespace std;
int main()
{
for (int i = 0; i < 10000; i ++ ) // 最高枚举到八位回文数
{
int a = i, b = i;
for (int j = 0; j < 4; j ++ )
while (b) a = a * 10 + b % 10, b /= 10;
if (a >= 1000 && a <= 9999)
cout << a << endl;
}
return 0;
}
#include
#include
#include
#include
using namespace std;
int days[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check(int date)
{
int year = date / 10000;
int month = date % 10000 / 100;
int day = date % 100;
if (!month || month > 12 || !day) return false;
if (month != 2 && day > days[month]) return false;
if (month == 2)
{
bool leap = year % 4 == 0 && year % 100 || year % 400 == 0;
if (day > 28 + leap) return false;
}
return true;
}
int getP(int x)
{
int a = x, b = x;
for (int j = 0; j < 4; j ++ )
a = a * 10 + b % 10, b /= 10;
return a;
}
int main()
{
int date1, date2;
cin >> date1 >> date2;
int res = 0;
for (int i = 0; i < 10000; i ++ )
{
int r = getP(i);
if (r >= date1 && r <= date2 && check(r)) res ++ ;
}
printf("%d\n", res);
return 0;
}
//枚举回文数 -> 判断是否在范围内 -> 判断日期是否合法
#include
#include
#include
using namespace std;
int main()
{
int w, m, n;
cin >> w >> m >> n;
m --, n -- ;
int x1 = m / w, x2 = n / w;
int y1 = m % w, y2 = n % w;
if (x1 % 2) y1 = w - 1 - y1;
if (x2 % 2) y2 = w - 1 - y2;
cout << abs(x1 - x2) + abs(y1 - y2) << endl;
return 0;
}
#include
#include
#include
#include
using namespace std;
int days[13] = {
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool check_vaild(int year, int month, int day)
{
if (month == 0 || month > 12 || day == 0) return false;
if (month != 2 && day > days[month]) return false;
if (month == 2)
{
bool leap = year % 4 == 0 && year % 100 || year % 400 == 0;
if (day > 28 + leap) return false;
}
return true;
}
int main()
{
int a, b, c;
scanf("%d/%d/%d", &a, &b, &c);
for (int data = 19600101; data <= 20591231; data ++)
{
int year = data / 10000, month = data % 10000 / 100, day = data % 100;
if (check_vaild(year, month, day))
{
if (year % 100 == a && month == b && day == c ||
month == a && day == b && year % 100 == c ||
day == a && month == b && year % 100 == c)
printf("%d-%02d-%02d\n", year, month, day);
}
}
return 0;
}
#include
using namespace std;
int main()
{
int a = 123456;
cout << a % 1000 << endl;//456
cout << a / 1000 << endl;//123
cout << a / 10000 << endl; // 12
cout << a / 100 % 100 << endl;//34
cout << a % 10000 / 100 << endl;//34
cout << a % 100 << endl;//56
cout << a % 10000 % 100 << endl;//56
return 0;
}
// 取余是得到除以此数的余数
#include
#include
#include
#include
using namespace std;
int get_seconds(int h, int m, int s)
{
return h * 3600 + m * 60 + s;
}
int get_time()
{
string line;
getline(cin, line);
if (line.back() != ')') line += " (+0)";
int h1, m1, s1, h2, m2, s2, d;
sscanf(line.c_str(), "%d:%d:%d %d:%d:%d (+%d)", &h1, &m1, &s1, &h2, &m2, &s2, &d);
return get_seconds(h2, m2, s2) - get_seconds(h1, m1, s1) + d * 24 * 3600;
}
int main()
{
int n;
scanf("%d", &n);
string line;
getline(cin, line); // 忽略掉第一行的回车
while (n -- )
{
int time = (get_time() + get_time()) / 2;
int hour = time / 3600, minute = time % 3600 / 60, second = time % 60;
printf("%02d:%02d:%02d\n", hour, minute, second);
}
return 0;
}
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 100010;
int n, m, T;
int score[N], last[N];
bool st[N];
PII order[N];
int main()
{
scanf("%d%d%d", &n, &m, &T);
for (int i = 0; i < m; i ++ ) scanf("%d%d", &order[i].x, &order[i].y);
sort(order, order + m);
for (int i = 0; i < m;)
{
int j = i;
while (j < m && order[j] == order[i]) j ++ ;
int t = order[i].x, id = order[i].y, cnt = j - i;
i = j;
score[id] -= t - last[id] - 1;
if (score[id] < 0) score[id] = 0;
if (score[id] <= 3) st[id] = false; // 以上处理的是t时刻之前的信息
score[id] += cnt * 2;
if (score[id] > 5) st[id] = true;
last[id] = t;
}
for (int i = 1; i <= n; i ++ )
if (last[i] < T)
{
score[i] -= T - last[i];
if (score[i] <= 3) st[i] = false;
}
int res = 0;
for (int i = 1; i <= n; i ++ ) res += st[i];
printf("%d\n", res);
return 0;
}
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;//pair 默认按第一关键字排序
const int N = 100010;
int n, d, k;
PII logs[N];
int cnt[N];
bool st[N]; // 记录每个帖子是否是热帖
int main()
{
scanf("%d%d%d", &n, &d, &k);
for (int i = 0; i < n; i ++ ) scanf("%d%d", &logs[i].x, &logs[i].y);
sort(logs, logs + n);
for (int i = 0, j = 0; i < n; i ++ ) // i < n 这里不是i < j
{
int id = logs[i].y;
cnt[id] ++ ;
while (logs[i].x - logs[j].x >= d)
{
int id = logs[j].y;
cnt[id] --;
j ++;
}
if (cnt[id] >= k) st[id] = true;
}
for (int i = 0; i <= 100000; i ++ )
if (st[i])
printf("%d\n", i);
return 0;
}
BFS可以找到最少步数因为BFS是按层搜索的
逻辑性的问题要一遍一遍的重复才可以记住
#include
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 210;
int n, m;
char g[N][N];
bool st[N][N];
PII q[N * N];
int dx[4] = {
-1, 0, 1, 0};
int dy[4] = {
0, 1, 0, -1};
int dist[N][N];
int bfs(PII start, PII end)
{
// queue q;
memset(dist, -1, sizeof dist);
memset(st, 0, sizeof st);
int tt = 0;
int hh = 0;
dist[start.x][start.y] = 0; //**
// q.push(start);
q[0] = start;
st[start.x][start.y] = 1;
while (hh <= tt)
{
// auto t = q.front();
// q.pop();
PII t = q[hh ++ ];
for (int i = 0; i < 4; i ++ )
{
int x = t.x + dx[i], y = t.y + dy[i];
if (x < 0 || x >= n || y < 0 || y >= m || g[x][y] == '#' || st[x][y]) continue; // 出界
dist[x][y] = dist[t.x][t.y] + 1;
if (end == make_pair(x, y)) return dist[x][y];
// q.push({x, y});
q[++ tt] = {
x, y};
st[x][y] = true;
}
}
return -1;
}
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
PII start, end;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
if (g[i][j] == 'S') start = {
i, j};
else if (g[i][j] == 'E') end = {
i, j};
int distance = bfs(start, end);
if (distance == -1) puts("oop!"); // 最后是有返回值的
else printf("%d\n", distance);
}
return 0;
}
#include
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 210;
int n, m;
char g[N][N];
int dist[N][N];
PII q[N * N];
int dx[4] = {
-1, 0, 1, 0};
int dy[4] = {
0, 1, 0, -1};
int bfs(PII start, PII end)
{
// queue q;
memset(dist, -1, sizeof dist);
int tt = 0;
int hh = 0;
dist[start.x][start.y] = 0;
// q.push(start);
q[0] = start;
while (hh <= tt)
{
// auto t = q.front();
// q.pop();
PII t = q[hh ++ ];
for (int i = 0; i < 4; i ++ )
{
int x = t.x + dx[i], y = t.y + dy[i];
if (x < 0 || x >= n || y < 0 || y >= m || g[x][y] == '#' || dist[x][y] != -1) continue; // 出界
dist[x][y] = dist[t.x][t.y] + 1;
if (end == make_pair(x, y)) return dist[x][y];
// q.push({x, y});
q[++ tt] = {
x, y};
}
}
return -1;
}
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
PII start, end;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < m; j ++ )
if (g[i][j] == 'S') start = {
i, j};
else if (g[i][j] == 'E') end = {
i, j};
int distance = bfs(start, end);
if (distance == -1) puts("oop!"); // 最后是有返回值的
else printf("%d\n", distance);
}
return 0;
}
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 25;
int n, m;
char g[N][N];
bool st[N][N];
PII q[N * N];
int dx[] = {
-1, 0, 1, 0};
int dy[] = {
0, 1, 0, -1};
int bfs(int sx, int sy)
{
// queue q;
// q.push({sx, sy});
memset(st,0,sizeof(st));
int tt = 0; int hh = 0;
q[0] = {
sx, sy};
st[sx][sy] = true;
// g[sx][sy] = '#';
int res = 0;
//q.size()
while (hh <= tt)
{
// auto t = q.front();
auto t = q[hh ++];
// q.pop();
res ++ ;
for (int i = 0; i < 4; i ++)
{
int x = t.x + dx[i], y = t.y + dy[i];
if (x < 0 || x >= n || y < 0 || y >= m || st[x][y] || g[x][y] != '.') continue;
// q.push({x, y});
q[++tt] = {
x, y};
// g[x][y] = '#';
st[x][y] = true;
}
}
return res;
}
int main()
{
while(cin >> m >> n, n || m)
{
for (int i = 0; i < n; i ++) cin >> g[i];
int x, y;
for (int i = 0; i < n; i ++)
for (int j = 0; j < m; j ++)
if (g[i][j] == '@')
{
x = i;
y = j;
}
cout << bfs(x, y) << endl;
}
return 0;
}
#include
#include
#include
using namespace std;
const int N = 10010;
int n;
int b[N];
bool st[N];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &b[i]);
int cnt = 0;
for (int i = 1; i <= n; i ++ )
if (!st[i])
{
cnt ++ ;
for (int j = i; !st[j]; j = b[j])
st[j] = true;
}
printf("%d\n", n - cnt);
return 0;
}
#include
#include
#include
#include
using namespace std;
const int N = 110;
struct Point
{
int x, y, z;
};
int L, R, C;
char g[N][N][N];
Point q[N * N * N];
int dist[N][N][N];
int dx[6] = {
1, -1, 0, 0, 0, 0};
int dy[6] = {
0, 0, 1, -1, 0, 0};
int dz[6] = {
0, 0, 0, 0, 1, -1};
int bfs(Point start, Point end)
{
int hh = 0, tt = 0;
q[0] = start;
memset(dist, -1, sizeof dist);
dist[start.x][start.y][start.z] = 0;
while (hh <= tt)
{
auto t = q[hh ++ ];
for (int i = 0; i < 6; i ++ )
{
int x = t.x + dx[i], y = t.y + dy[i], z = t.z + dz[i];
if (x < 0 || x >= L || y < 0 || y >= R || z < 0 || z >= C) continue; // 出界
if (g[x][y][z] == '#') continue; // 有障碍物
if (dist[x][y][z] != -1) continue; // 之前走到过
dist[x][y][z] = dist[t.x][t.y][t.z] + 1;
if (x == end.x && y == end.y && z == end.z) return dist[x][y][z];
q[ ++ tt] = {
x, y, z};
}
}
return -1;
}
int main()
{
while (scanf("%d%d%d", &L, &R, &C), L || R || C)
{
Point start, end;
for (int i = 0; i < L; i ++ )
for (int j = 0; j < R; j ++ )
{
scanf("%s", g[i][j]);
for (int k = 0; k < C; k ++ )
{
char c = g[i][j][k];
if (c == 'S') start = {
i, j, k};
else if (c == 'E') end = {
i, j, k};
}
}
int distance = bfs(start, end);
if (distance == -1) puts("Trapped!");
else printf("Escaped in %d minute(s).\n", distance);
}
return 0;
}
//while头入队标记 for尾出队统计
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n;
char g[N][N];
bool st[N][N];
PII q[N * N];
int dx[4] = {
-1, 0, 1, 0};
int dy[4] = {
0, 1, 0, -1};
void bfs(int sx, int sy, int &total, int &bound)
{
int hh = 0, tt = 0;// (int tt =0, hh = 0;正确) (int tt, hh = 0 错误)
q[0] = {
sx, sy};
st[sx][sy] = true; // 入队标记
while (hh <= tt)
{
// while循环的头部出队 for循环的尾部入队。
PII t = q[hh ++ ];
total ++ ; // 出队统计
bool is_bound = false;
for (int i = 0; i < 4; i ++ )
{
int x = t.x + dx[i], y = t.y + dy[i];
if (x < 0 || x >= n || y < 0 || y >= n || st[x][y] ) continue; // 出界
if (g[x][y] == '.')
{
is_bound = true; // 每一个点访问四个方向,只要有一个方向符合条件就满足。
//不能直接在这里bound++
continue;
}
q[ ++ tt] = {
x, y};
st[x][y] = true; //入队标记
}
if (is_bound) bound ++ ;
}
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
int cnt = 0;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
if (!st[i][j] && g[i][j] == '#')
{
int total = 0, bound = 0;
bfs(i, j, total, bound);
if (total == bound) cnt ++ ;
}
printf("%d\n", cnt);
return 0;
}
//用vector存储图
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int n;
struct Edge
{
int id, w;
};
vector<Edge> h[N];
int dist[N];
void dfs(int u, int father, int distance)
{
dist[u] = distance;
for (auto node : h[u])
if (node.id != father)
dfs(node.id, u, distance + node.w);
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n - 1; i ++ )
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
h[a].push_back({
b, c});
h[b].push_back({
a, c});
}
dfs(1, -1, 0);
int u = 1;
for (int i = 1; i <= n; i ++ )
if (dist[i] > dist[u])
u = i;
dfs(u, -1, 0);
for (int i = 1; i <= n; i ++ )
if (dist[i] > dist[u])
u = i;
int s = dist[u];
printf("%lld\n", s * 10 + s * (s + 1ll) / 2);
return 0;
}
#include
int main()
{
long long n;
scanf("%lld", &n);
while(n) printf("%lld ", n), n >>= 1; //逗号表达式
return 0;
}
// for(;n;n>>=1) 等价于 while(n!=0) n=n/2
#include
#include
using namespace std;
int main()
{
string s, res;
cin >> s;
for (int i = 0; i < s.size(); i ++ )
if (i + 1 < s.size() && s[i + 1] <= '9')
{
int k = s[i + 1] - '0';
while (k -- ) res += s[i];
i ++ ;
}
else
{
res += s[i];
}
cout << res << endl;
return 0;
}
注意题干要求,如果行号和列数都是偶数,不能走入这一格中。
不能走的地方不走就可以了 全局变量的整型数组默认赋值为0 所以跳过就行
#include
#include
using namespace std;
const int N = 40;
int n, m;
int f[N][N];
int main()
{
cin >> n >> m;
f[1][1] = 1;
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
{
if (i == 1 && j == 1) continue;
if (i % 2 || j % 2)
f[i][j] = f[i - 1][j] + f[i][j - 1];
}
cout << f[n][m] << endl;
return 0;
}
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100010;
int n, m;
int a[N], s[11][N];
int main()
{
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
for (int i = 0; i < n; i ++ )
{
LL t = a[i] % m;
for (int j = 0; j < 11; j ++ )
{
s[j][t] ++ ;
t = t * 10 % m;
}
}
LL res = 0;
for (int i = 0; i < n; i ++ )
{
LL t = a[i] % m;
int len = to_string(a[i]).size();
res += s[len][(m - t) % m];
LL r = t;
while (len -- ) r = r * 10 % m;
if (r == (m - t) % m) res -- ;
}
printf("%lld\n", res);
return 0;
}