题目链接:http://codeforces.com/contest/761
A. Dasha and Stairs
题意:给定奇数偶数个数寻找一个满足条件的队列,很显然,奇偶数相差必须为不超过1才行。
解法:
#include <bits/stdc++.h>
using namespace std;
int main(){
int a,b;
scanf("%d%d",&a,&b);
if(a==0&&b==0) puts("NO");
else if(abs(a-b)<=1) puts("YES");
else puts("NO");
return 0;
}
B. Dasha and friends
题意:有两个人在任意一个起点逆时针奔跑,这个圈长度为L,其中有N个障碍点,给出每个人逆时针奔跑的时候跑多长距离会遇到一个障碍物,问两人跑的是否是一个地图。
解法:自己O(n^2)枚举出发的位置暴力即可,数据范围大也是可以做,可以用最小表示法。
#include <bits/stdc++.h>
using namespace std;
int n,L;
bool vis[110];
int b[110];
int main(){
scanf("%d%d",&n,&L);
for(int i=1; i<=n; i++){
int x;
scanf("%d", &x);
vis[x]=1;
}
for(int i=1; i<=n; i++) scanf("%d", &b[i]);
for(int i=1; i<=L; i++){
bool ok = 1;
for(int j=1; j<=n; j++){
int tmp=i+b[j];
tmp=(tmp+L)%L;
if(!vis[tmp]){
ok=0;break;
}
}
if(ok==1){
puts("YES");
return 0;
}
}
puts("NO");
return 0;
}
C. Dasha and Password
题意:有n个串,每个串有m个字符,可以由数字,小写字母,和三个符号组成,现在要在这n个串中每个串找出一个字符组成一个密码,这密码要求至少要有一个数字,一个字母和一个特殊字符,一开始每个字符串都指在第一个字符,每次移动可以往两边移动,也就是说可以往左右两边移动,要求所得到的密码移动的次数最少。
解法:要求最少的次数,所以移动最少的串,每个串移动最少的次数就行了,所以要求三个至少,所以我们可以找出三个串,每个串移动来找到一个条件,最后枚举最多50*49*48种情况,三个for循环就行。
#include <bits/stdc++.h>
using namespace std;
string s[55];
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>s[i];
}
int ans=1e9;
for(int i=0; i<n; i++){//digit
for(int j=0; j<n; j++){//lowercase
for(int k=0; k<n; k++){//'#','*','&'
if(i==j||i==k||j==k) continue;
int sz = s[i].size();
int d1 = 1e9;
for(int l=0; l<sz; l++){
if(isdigit(s[i][l])){
d1 = min(d1, min(l, sz-l));
}
}
sz = s[j].size();
int d2 = 1e9;
for(int l=0; l<sz; l++){
if(islower(s[j][l])){
d2 = min(d2, min(l, sz-l));
}
}
sz = s[k].size();
int d3 = 1e9;
for(int l=0; l<sz; l++){
if(s[k][l]=='#'||s[k][l]=='*'||s[k][l]=='&'){
d3 = min(d3, min(l, sz-l));
}
}
if(d1==1e9||d2==1e9||d3==1e9) continue;
ans = min(ans, d1+d2+d3);
}
}
}
printf("%d\n", ans);
return 0;
}
D. Dasha and Very Difficult Problem
题意::序列bi=ci+ai,给出ai和将ci离散化后的pi,问在l,r中能否找出这样一个任意解。
解法:通过ci和pi,我们可以得到bi的最小情况,通过平移区间,将bi平移到l,r内即可。
#include<iostream>
#include<iostream>
using namespace std;
int n, l, r;
int a[100005];
int b[100005];
int p[100005];
int main()
{
cin >> n >> l >> r;
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
cin >> p[i];
int ma = - 1e9 + 5, mi = 1e9 + 5;
for (int i = 0; i < n; ++i)
{
b[i] = a[i] + p[i];
ma = max(ma, b[i]);
mi = min(mi, b[i]);
}
if (ma - mi > r - l)
cout << "-1";
else
{
int temp;
if (mi < l)
temp = l - mi;
else temp = r - ma;
for (int i = 0; i < n; ++i)
cout << b[i] + temp << " ";
}
}
E. Dasha and Puzzle
题意:给你一棵树,让你在二维平面上摆出来,边必须平行坐标轴,且边没有交集
解法:
如果存在某点度数大于4肯定不行。
然后,第一层让边长为len,第二层边长为len/2,第三层边长为len/4……
这样弄下去就好了,这样就保证每一层都不会碰到上一层了。即缩小距离的方法。#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 40;
const int d[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
struct edge{
int to,next;
edge(){}
}E[maxn*2];
int n, head[maxn],du[maxn], edgecnt;
void init(){
memset(head,-1,sizeof(head));
edgecnt=0;
}
void add(int u, int v){
E[edgecnt].to = v, E[edgecnt].next = head[u], head[u] = edgecnt++;
}
pair <LL,LL> ans[maxn];
void dfs(int u, int fa, LL x, LL y, LL dis, int dir){
int j=0;
ans[u] = {x, y};
for(int i=head[u];~i;i=E[i].next){
int v = E[i].to;
if(v == fa) continue;
if(j+dir==3) j++;
dfs(v, u, x+d[j][0]*dis, y+d[j][1]*dis, dis/2, j);
j++;
}
}
int main(){
init();
scanf("%d", &n);
for(int i=1; i<n; i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
du[x]++;
du[y]++;
}
for(int i=1; i<=n; i++){
if(du[i]>4){
return 0*printf("NO\n");
}
}
printf("YES\n");
dfs(1, 0, 0, 0, 1<<30, -1);
for(int i=1; i<=n; i++){
printf("%lld %lld\n", ans[i].first, ans[i].second);
}
return 0;
}
F. Dasha and Photos
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 1002;
const int maxq = 3e5+10;
struct node{
int u1,v1,u2,v2,c;
}q[maxq];
int a[maxn][maxn], cnt[26][maxn][maxn];//cnt(c,i,j)为(i,j)在给定的子矩阵中且变成的字符是c的图的个数
//f[i][j]为所有图(i,j)位置与原图(i,j)位置距离之和:sum1(i,j)=sigma(c='a' to 'z')cnt1(c,i,j)*abs(c-a[i][j])
//sum1[i][j]为f从(1,1)到(i,j)的前缀和
//cnt2[c][i][j]为(i,j)是c的图的个数(不要求(i,j)在给定的子矩阵中)
//sum2[c][i][j]为cnt2的二维前缀和
LL sum1[maxn][maxn], sum2[26][maxn][maxn];
int n,m,K;
int main(){
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<=n;i++){
char str[maxn];
scanf("%s", str+1);
for(int j=1;j<=m;j++){
a[i][j]=str[j]-'a';
}
}
for(int i=1;i<=K;i++){
char typ[3];
scanf("%d %d %d %d", &q[i].u1,&q[i].v1,&q[i].u2,&q[i].v2);
scanf("%s", typ);
q[i].c = typ[0]-'a';
++cnt[q[i].c][q[i].u1][q[i].v1];
--cnt[q[i].c][q[i].u1][q[i].v2+1];
--cnt[q[i].c][q[i].u2+1][q[i].v1];
++cnt[q[i].c][q[i].u2+1][q[i].v2+1];
}
for(int i=1; i<=n; i++){
for(int j=1; j<=m; j++){
LL fij, tot;
fij = 0;
tot = K;
for(int c=0; c<26; c++){
cnt[c][i][j] += cnt[c][i-1][j];
cnt[c][i][j] += cnt[c][i][j-1];
cnt[c][i][j] -= cnt[c][i-1][j-1];
fij += cnt[c][i][j]*abs(a[i][j]-c);
tot -= cnt[c][i][j];
}
sum1[i][j]=fij+sum1[i-1][j]+sum1[i][j-1]-sum1[i-1][j-1];
for(int c=0; c<26; c++){
sum2[c][i][j]=cnt[c][i][j]+sum2[c][i-1][j]+sum2[c][i][j-1]-sum2[c][i-1][j-1];
if(a[i][j]==c){
sum2[c][i][j] += tot;
}
}
}
}
LL sum, ans = 1e18;
for(int i=1; i<=K; i++){
int u1 = q[i].u1, v1 = q[i].v1, u2 = q[i].u2, v2 = q[i].v2, c0 = q[i].c;
sum = sum1[n][m]-(sum1[u2][v2]-sum1[u1-1][v2]-sum1[u2][v1-1]+sum1[u1-1][v1-1]);
for(int c=0; c<26; c++){
sum += (sum2[c][u2][v2]-sum2[c][u1-1][v2]-sum2[c][u2][v1-1]+sum2[c][u1-1][v1-1])*abs(c-c0);
}
ans = min(ans, sum);
}
printf("%lld\n", ans);
return 0;
}