The Next Moment
题解
直接用DFS
处理,时,分,秒,然后一个个的枚举,就可以了,将不符合条件的去掉,取个最小的,对于第二天的时间需要加个24∗3600,这道题目做的我都尴尬了,直接%d:%d:%d
竟然过不了,只有先读取字符串,然后用字符串处理才可以,也是让我刷新了对出题人的奇葩程度
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)
using namespace std;
const int MAXN = 100 + 5;
const int INF = 0x3f3f3f3f;
bool vis[MAXN];
vector<int> vs;
int time_ts[3], mtime_ts[3];
int mc;
int limits[3] = {24, 60, 60};
char ch[MAXN];
void dfs(int x, int &nt) {
if(x >= 3) {
int ys = time_ts[0] * 3600 + time_ts[1] * 60 + time_ts[2];
int c = ys - nt;
if(c <= 0) {
c += limits[0] * 3600;
}
if(c < mc) {
mc = c;
mtime_ts[0] = time_ts[0];
mtime_ts[1] = time_ts[1];
mtime_ts[2] = time_ts[2];
}
return;
}
for(int i = 0; i < vs.size(); i ++) {
for(int j = 0; j < vs.size(); j ++) {
int t = vs[i] * 10 + vs[j];
if(t >= limits[x]) continue;
time_ts[x] = t;
dfs(x + 1, nt);
}
}
}
void scan(int &h, int &m, int &s){
scanf("%s", ch);
int len = strlen(ch);
int k = 0;
for(int i = 0;i < len;i ++){
if(isdigit(ch[i])) {
ch[k] = ch[i];
k ++;
}
}
h = (ch[0] - '0') * 10 + ch[1] - '0';
m = (ch[2] - '0') * 10 + ch[3] - '0';
s = (ch[4] - '0') * 10 + ch[5] - '0';
}
int main() {
int _;
//FIN;
//FOUT;
scanf("%d", &_);
while(_ --) {
int hh, mm, ss;
scan(hh, mm, ss);
//scanf("%d:%d:%d", &hh, &mm, &ss);
memset(vis, false, sizeof(vis));
vs.clear();
int nt = hh * 3600 + mm * 60 + ss;
int thh = hh, tmm = mm, tss = ss;
for(int i = 0; i < 2; i ++) {
vis[hh % 10] = true;
hh /= 10;
vis[mm % 10] = true;
mm /= 10;
vis[ss % 10] = true;
ss /= 10;
}
for(int i = 0; i < MAXN; i ++) {
if(vis[i]) vs.push_back(i);
}
mtime_ts[0] = thh;
mtime_ts[1] = tmm;
mtime_ts[2] = tss;
mc = limits[0] * 3600;
dfs(0, nt);
printf("%02d:%02d:%02d\n", mtime_ts[0], mtime_ts[1], mtime_ts[2]);
}
return 0;
}
回文子串的数量
题解
题目意思基本可以理解为,求解这个字符串存在多少个回文子串,我们先提一个概念就是,如果你知道以i为中心的最长回文子串,那么该最长回文子串覆盖的区间中存在的回文子串的个数就是
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)
using namespace std;
typedef long long LL;
const int MAXN = 8e5 + 5;
const int INF = 0x3f3f3f3f;
int len[MAXN << 1];
char S[MAXN];
int sz;
char tS[MAXN << 1];
void solve() {
int mx = 0, id = 0;
for(int i = 1; i < sz; i ++) {
if(mx > i) {
len[i] = min(len[2 * id - i], mx - i);
} else {
len[i] = 1;
}
while(i - len[i] >= 1 && i + len[i] < sz && tS[i + len[i]] == tS[i - len[i]]) len[i] ++;
if(len[i] + i > mx) {
mx = len[i] + i;
id = i;
}
}
LL ans = 0;
for(int i = 1; i < sz; i ++) {
ans += len[i] / 2;
//printf("[%d]\n", len[i]);
}
printf("%lld\n", ans);
}
int main() {
while(~scanf("%s", S)) {
sz = 1;
int len_t = strlen(S);
memset(len, 0, sizeof(len));
for(int i = 0; i < len_t; i ++) {
tS[sz ++] = '#';
tS[sz ++] = S[i];
}
tS[sz ++] = '#';
solve();
}
return 0;
}
紧张的会议室
题解
题目很简单,解决方案个人也很简单,很明显,数据很大Si,Ei都有109,所以常规方案不能做,先想到离散,或者说只处理出现的边界,所以先将所有的数据离线,然后可以得到最多2×105个数据,然后从左往右维护两个优先队列,第一个优先队列,保存的最开始的会议时间,第二优先队列维护的后面尝试加入的会议时间,如果第一个优先队列的个数≥M,那么第二个优先队列中的所有会议都是冲突的,优先队列排序是针对结束时间了,用了类似于单调队列的处理思路。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <unordered_set>
#include <vector>
#define FIN freopen("input.txt", "r", stdin)
#define FOUT freopen("output.txt", "w", stdout)
using namespace std;
typedef long long LL;
const int MAXN = 4e5 + 5;
const int INF = 0x3f3f3f3f;
int N, M;
unordered_set<int> usi;
struct t_seq{
int s, t, id;
t_seq(int s, int t):s(s), t(t){
}
bool operator > (const t_seq & p) const{
return !(*this < p);
}
bool operator < (const t_seq &p) const{
return t < p.t;
}
};
bool cmp(const t_seq & p, const t_seq & q){
return p.s < q.s;
}
vector<t_seq> v1, v2;
vector<int> t_list;
priority_queue<t_seq, vector<t_seq>, greater<t_seq> > pqt1, pqt2;
bool vis[MAXN];
int main() {
while(~scanf("%d%d", &N, &M)){
v1.clear();
v2.clear();
t_list.clear();
usi.clear();
while(!pqt1.empty()) pqt1.pop();
while(!pqt2.empty()) pqt2.pop();
memset(vis, false, sizeof(vis));
int t, s;
for(int i = 0;i < N;i ++){
scanf("%d%d", &s, &t);
v1.push_back(t_seq(s, t));
usi.insert(s);
usi.insert(t);
}
int Q;
scanf("%d", &Q);
for(int i = 0;i < Q;i++){
scanf("%d%d", &s, &t);
t_seq ts(s, t);
ts.id = i;
v2.push_back(ts);
usi.insert(s);
usi.insert(t);
}
for(unordered_set<int>::iterator it = usi.begin(); it != usi.end();it ++){
t_list.push_back(*it);
}
sort(t_list.begin(), t_list.end());
sort(v1.begin(), v1.end(), cmp);
sort(v2.begin(), v2.end(), cmp);
int p1 = 0, p2 = 0;
for(int i = 0;i < t_list.size();i ++){
while(pqt1.size() && pqt1.top().t <= t_list[i]) pqt1.pop();
while(pqt2.size() && pqt2.top().t <= t_list[i]) pqt2.pop();
while(p1 < v1.size() && v1[p1].s == t_list[i]){
pqt1.push(v1[p1 ++]);
}
while(p2 < v2.size() && v2[p2].s == t_list[i]){
pqt2.push(v2[p2 ++]);
}
if(pqt1.size() >= M) {
while(!pqt2.empty()){
vis[pqt2.top().id] = true;
pqt2.pop();
}
}
}
for(int i = 0;i < Q;i ++){
printf("%s\n", vis[i] ? "NO" : "YES");
}
}
return 0;
}