先简单总结一下,这次比赛的情况。这次比赛吧,是非常不理想的。
1.首先,就是审题方面,我的审题是不太行的,全队审题靠小龙,汗。。
2.接着是做题的节奏方面,做题的节奏这次也明显没有上次好,这次有点太急躁的感觉,提交的太急,审题太粗糙,也没有发挥好组队的优势。
3.其次,就是敲代码前,思路要尽量沉淀,不要脑袋一发热就敲了,占用团队时间,还影响士气,一定要尽量和队友都沟通思路,都认为可以才可以动手,简单题除外。
题目解释:俩个人约定在(x, y)点见面, 但没有指定坐标原点,且俩人一个在左下方,一个在右上方,看俩人是否碰面。
分析:水题,看约定地点x, y是否为,俩边中点。
#include
using namespace std;
int n, m, x, y;
int main()
{
while(scanf("%d%d%d%d", &n, &m, &x, &y) != EOF)
{
if(2 * x == n && 2 * y == m) printf("YES\n");
else printf("NO\n");
}
return 0;
}
题意给n个数,求组合出的最小奇数。
#include
using namespace std;
const int maxn = 120;
int n, a[maxn];
int main()
{
while(scanf("%d", &n) != EOF)
{
int odd = 10, re, sum = 0;
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
sum += a[i];
if(a[i] % 2 != 0)
{
if(odd > a[i])
{
odd = min(odd, a[i]), re = i;
}
}
}
if(odd == 10) {
printf("-1\n");
continue;
}
else if(odd == sum && n != 1)
{
printf("-1\n");
continue;
}
else
{
a[re] = 15;
sort(a, a + n);
for(int i = n - 2; i >= 0; --i) printf("%d", a[i]);
printf("%d\n", odd);
}
}
return 0;
}
D题尺取法,比较难得一题了,其实也不是特别难,就是没有想到罢了,。。。哈哈哈。
注意点:
1.尺取法但大于K个数存在时,前置点前移动。
2.一段内得子串数目,1 + 2 + 。。。+ n
#include
using namespace std;
int t, sum[50], k;
string str;
int main()
{
scanf("%d", &t);
while(t--)
{
memset(sum, 0, sizeof(sum));
cin >> str;
scanf("%d", &k);
int len = str.size(), pos = 0;
long long ans = 0;
for(int i = 0; i < len; ++i)
{
sum[str[i] - 'a' + 1]++;
while(sum[str[i] - 'a' + 1] > k)
{
sum[str[pos] - 'a' + 1]--;
pos++;
}
ans = ans + i - pos + 1;
}
printf("%lld\n", ans);
}
return 0;
}
删掉n个数使存在的不同得数目尽量多。
#include
using namespace std;
int a, b[110], c, sum, num;
int main()
{
while(scanf("%d", &a) != EOF)
{
memset(b, 0, sizeof(b)); sum = 0, num = 0;
for(int i = 0; i < a; i++)
{
int t;
scanf("%d", &t); b[t]++;
}
for(int i = 0; i <= 100; i++)
{
if(b[i]) sum += (b[i] - 1), num++;
}
scanf("%d", &c);
if(c <= sum) printf("%d\n", num);
else printf("%d\n", num - (c - sum));
}
return 0;
}
DP题+单调队列维护。
状态转移方程蛮简单得
dp = min(min(dp[i - l](l <= t) ) + 1, dp[i/k])+1)
优先队列维护需要注意的点
1.注意我们要的使最小的dp[i - l]
#include
using namespace std;
const int maxn = 1000100;
int T, x, k, t, dp[maxn], Q[maxn];
int main()
{
scanf("%d", &T);
while(T--)
{
memset(dp, 0x3f, sizeof(dp));
scanf("%d%d%d", &x, &k, &t);
if(k == 0)
{
if((x - 1) % t == 0)
printf("%d\n", (x - 1) / t);
else
printf("%d\n", (x - 1) / t + 1);
continue;
}
if(t == 0)
{
int ans = 0;
while(x != 1)
{
x /= k;
ans++;
}
printf("%d\n", ans);
continue;
}
int head = 1, tail = 1;
dp[1] = 0;
Q[1] = 1;
for(int i = 2; i <= x; i++)
{
while(head <= tail && Q[head] < i - t)
head++;
if(head <= tail) dp[i] = dp[Q[head]] + 1;
if(i % k == 0) dp[i] = min(dp[i], dp[i / k] + 1);
while(head <= tail && dp[i] <= dp[Q[tail]]) tail--;
Q[++tail] = i;
}
printf("%d\n", dp[x]);
}
return 0;
}
注意点:
1.i, j, k为等比数列。
2.j | i 或 j|k 所以j只能在中间
3.枚举公比注意不要爆int
#include
#include
using namespace std;
const int maxn = 10010;
int t;
string ch;
char str[maxn];
int main()
{
scanf("%d", &t);
while(t--)
{
cin >> ch;
int len = ch.size();
int re = 1;
for(int i = 0; i < len; ++i)
{
str[i + 1] = ch[i];
if(str[i + 1] != 'x' && str[i + 1] != 'y' && str[i + 1] != 'r')
str[i + 1] = ' ';
}
long long ans = 0;
for(int i = 1; i < len - 1; i++)
{
for(int j = 1; (long long)i * j * j<= len; j++)
{
if(str[i] == ' ' || str[i * j] == ' ' || str[i * j * j] == ' ') continue;
if(str[i] != str[i * j] && str[i] != str[i *j * j] && str[i * j] != str[i * j * j] && str[i * j] == 'r')
ans++;
}
}
printf("%lld\n", ans);
}
return 0;
}