每一篇日志有俩个属性时间ts和编号id。如果在长度为D的时间段内收到不少于K个赞,就是热帖。求特贴的数目。
有俩种思路:1.先遍历帖子,再遍历时间段, 2.先遍历时间段,再遍历帖子。但是这俩种暴力都会超时。所以需要优化,可以发现先遍历时间段再遍历帖子的算法,第二重循环会有一段重复的部分,因此可以优化。同时记录俩端的指针,当时间段长于D的时候,就将前面一个帖子数减去1。
#include
#include
#include
using namespace std;
const int N=100010;
#define x first
#define y second
typedef pair PII;
PII logs[N];
bool st[N];
int cnt[N];
int main()
{
int n,d,k;
scanf("%d%d%d",&n,&d,&k);
for(int i=0;i=d)
{
cnt[logs[j].y]--;
j++;
}
if(cnt[id]>=k) st[id]=true;
}
for(int i=0;i
在给定的二维矩阵中找一条可行的最短路径,求最短路径是多少,如果没有,输出oop!
第一行是一个正整数 T,表示一共有 T 组数据。
每一组数据的第一行包含了两个用空格分开的正整数 R 和 C,表示地图是一个 R×C 的矩阵。
这道题就是一道简单的宽搜题,宽搜题需要定义
1.一个存储地图的二维数组
2.一个判断是否已经走过的st数组(如果需要求距离,可以用dist替代)
3.一个队列,可以用c++的也可以用数组模拟
本题每次更新距离之后,判断一下该点是否是重点,是最快结束的。
#include
#include
#include
#include
#include
#define x first
#define y second
using namespace std;
typedef pair PII;
const int N = 210;
int n, m;
char g[N][N];
int dist[N][N];
int bfs(PII start, PII end)
{
queue q;
memset(dist, -1, sizeof dist);
dist[start.x][start.y] = 0;
q.push(start);
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
while (q.size())
{
auto t = q.front();
q.pop();
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) continue; // 出界
if (g[x][y] == '#') continue; // 障碍物
if (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});
}
}
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;
}
有 N个瓶子,编号 1∼N,放在架子上。要求每次拿起 2 个瓶子,交换它们的位置。
经过若干次后,使得瓶子的序号从小到大排列。如;
瓶子:2 1 3 5 4
-------->
位置:1 2 3 4 5
求最少要交换多少次?
本题思路比较精巧,是个图论和环的题目。可以将每个瓶子看成点,向瓶子应该在的位置的瓶子连边,构成环。
做交换:
交换一:环内的点交换—>每次将环列成俩个
交换二: 环之间的点交换–>每次合并俩个环
由于最后要得到的情况是每个点都和自己连城一个环,所有最后有n个环,最少要做n-k次交换,k环的个数。题目就转化为了求环的个数。
#include
#include
using namespace std;
const int N=10010;
int b[N];
bool st[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>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;
}
cout<