题目链接:http://codeforces.com/contest/816
Karen is getting ready for a new school day!
![](https://i-blog.csdnimg.cn/blog_migrate/fa676644715b5c28f7b60824cc612f49.png)
It is currently hh:mm, given in a 24-hour format. As you know, Karen loves palindromes, and she believes that it is good luck to wake up when the time is a palindrome.
What is the minimum number of minutes she should sleep, such that, when she wakes up, the time is a palindrome?
Remember that a palindrome is a string that reads the same forwards and backwards. For instance, 05:39 is not a palindrome, because 05:39 backwards is 93:50. On the other hand, 05:50 is a palindrome, because 05:50 backwards is 05:50.
The first and only line of input contains a single string in the format hh:mm (00 ≤ hh ≤ 23, 00 ≤ mm ≤ 59).
Output a single integer on a line by itself, the minimum number of minutes she should sleep, such that, when she wakes up, the time is a palindrome.
05:39
11
13:31
0
23:59
1
In the first test case, the minimum number of minutes Karen should sleep for is 11. She can wake up at 05:50, when the time is a palindrome.
In the second test case, Karen can wake up immediately, as the current time, 13:31, is already a palindrome.
In the third test case, the minimum number of minutes Karen should sleep for is 1 minute. She can wake up at 00:00, when the time is a palindrome.
解析:求下个时刻的回文串,直接模拟就好了
代码:
#include<bits/stdc++.h>
#define N 2000009
using namespace std;
typedef long long LL;
bool check(int h, int m)
{
if(h == m && !h) return true;
char s[109];
if(h < 10)
{
s[0] = '0';
s[1] = h % 10 + '0';
}
else
{
s[1] = h % 10 + '0'; h /= 10;
s[0] = h % 10 + '0';
}
if(m < 10)
{
s[2] = '0';
s[3] = m % 10 + '0';
}
else
{
s[3] = m % 10 + '0'; m /= 10;
s[2] = m % 10 + '0';
}
for(int i = 0, j = 3; i <= j; i++, j--)
{
if(s[i] != s[j]) return false;
}
return true;
}
int main()
{
int h, m, ans = 0;
scanf("%d:%d", &h, &m);
while(true)
{
if(check(h, m)) break;
m++;
if(m >= 60) h = (h + 1) % 24;
m = m % 60;
ans++;
}
printf("%d\n", ans);
return 0;
}
解析:求每个数在所有区间中出现了几次,咱可以用一个数组标记一下,每次加加,最后求前缀和,但这样会超时; 思路2(学长的思路,逃,,,):就是把所有加加去掉,变成每遇到一个区间[l, r], vis[l]++, vis[r+1]--,然后遍历一遍vis[i] += vis[i-1],再求一下前缀和,最后直接输出sum[r]-sum[l-1]
代码:
#include<bits/stdc++.h>
#define N 200009
using namespace std;
typedef long long LL;
int a[N], sum[N];
int main()
{
memset(a, 0, sizeof(a));
sum[0] = 0;
int n, k, q, l, r;
scanf("%d%d%d", &n, &k, &q);
for(int i = 1; i <= n; i++)
{
scanf("%d%d", &l, &r);
a[l]++; a[r+1]--;
}
for(int i = 1; i < N; i++)
{
a[i] += a[i-1];
}
for(int i = 1; i < N; i++)
{
if(a[i] >= k) a[i] = 1;
else a[i] = 0;
}
//for(int i = 90; i <= 100; i++) cout << a[i] << endl;
for(int i = 1; i < N; i++)
{
sum[i] = sum[i-1] + a[i];
}
while(q--)
{
scanf("%d%d", &l, &r);
printf("%d\n", sum[r] - sum[l-1]);
}
return 0;
}
解析:直接模拟下,注意m==1||n==1的情况,这题是上午刚补的题,昨天晚上没做对,弱鸡一个
代码:
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<cctype>
#define N 5009
using namespace std;
int mp[N][N], x[5000009], y[5000009];
int x_len, y_len;
int m, n;
void get_x()
{
for(int i = 1; i <= m; i++)
{
int k = 0x3f3f3f3f;
for(int j = 1; j <= n; j++)
{
k = min(k, mp[i][j]);
}
for(int j = 1; j <= n; j++) mp[i][j] -= k;
while(k--)
{
x[x_len++] = i;
}
}
}
void get_y()
{
for(int j = 1; j <= n; j++)
{
int k = 0x3f3f3f3f;
for(int i = 1; i <= m; i++)
{
k = min(k, mp[i][j]);
}
for(int i = 1; i <= m; i++) mp[i][j] -= k;
while(k--)
{
y[y_len++] = j;
}
}
}
bool check()
{
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if(mp[i][j]) return false;
}
}
return true;
}
int main()
{
scanf("%d%d", &m, &n);
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++) scanf("%d", &mp[i][j]);
}
x_len = y_len = 0;
if(n <= m)
{
get_y(); get_x();
}
else
{
get_x(); get_y();
}
if(!check()) puts("-1");
else
{
printf("%d\n", x_len + y_len);
for(int i = 0; i < x_len; i++) printf("row %d\n", x[i]);
for(int i = 0; i < y_len; i++) printf("col %d\n", y[i]);
}
return 0;
}