A. Chewbaсca and Number
题目链接
http://codeforces.com/contest/514/problem/A
题目大意
给你一个数字,你可以对其每一位进行翻转操作:假如原来这个数字大小为
i
,翻转后就变为
思路
水题
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 110
using namespace std;
int n;
char A[MAXN],B[MAXN];
char ans[MAXN];
int main()
{
scanf("%s",A+1);
n=strlen(A+1);
if(9-(A[1]-'0')<=(A[1]-'0')&&(9-(A[1]-'0')))
B[1]='0'+(9-(A[1]-'0'));
else B[1]=A[1];
for(int i=2;i<=n;i++)
{
if(9-(A[i]-'0')<=(A[i]-'0'))
B[i]='0'+(9-(A[i]-'0'));
else B[i]=A[i];
}
printf("%s\n",B+1);
return 0;
}
B. Han Solo and Lazer Gun
题目链接
http://codeforces.com/contest/514/problem/B
题目大意
给你
n
个点,问有多少个子集,使得子集里每个点和
思路
枚举每个点,得到它们各自和 (x0,y0) 的连线的斜率,然后用并查集合并斜率相同的点即可。
注意此题卡double精度,还有要注意分母为0的情况,判断斜率是否相同时最好做移项,使用整数运算,避免除法
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <cmath>
#define MAXN 1100
#define EPS 1e-10
using namespace std;
int n;
typedef pair<int,int> pr;
pr points[MAXN],center;
int f[MAXN];
int findSet(int x)
{
if(f[x]==x) return f[x];
return f[x]=findSet(f[x]);
}
int main()
{
for(int i=1;i<MAXN;i++) f[i]=i;
scanf("%d%d%d",&n,¢er.first,¢er.second);
for(int i=1;i<=n;i++)
scanf("%d%d",&points[i].first,&points[i].second);
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(!(points[i].second-center.second)||!(points[j].second-center.second)) continue;
if((points[i].first-center.first)*(points[j].second-center.second)==(points[j].first-center.first)*(points[i].second-center.second))
{
f[findSet(i)]=f[findSet(j)];
}
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
if(!(points[i].second-center.second)&&!(points[j].second-center.second))
{
f[findSet(i)]=f[findSet(j)];
}
}
int tot=0;
for(int i=1;i<=n;i++)
{
if(findSet(i)==i) tot++;
}
printf("%d\n",tot);
return 0;
}
C. Watto and Mechanism
题目链接
http://codeforces.com/contest/514/problem/C
题目大意
给你
n
个字符串,
思路
把所有的串插入进trie树里,然后每次询问把
说起来比较绕口,还是看代码比较清楚吧
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <cmath>
#define MAXN 610000
#define EPS 1e-10
using namespace std;
int n,m;
char s[MAXN];
int ch[MAXN][26],nCount=0,root=0;
void Insert()
{
int len=strlen(s+1),p=root;
for(int i=1;i<=len;i++)
{
if(!ch[p][s[i]-'a']) ch[p][s[i]-'a']=++nCount;
p=ch[p][s[i]-'a'];
}
}
int len;
bool DFS(int pos,int p,bool flag)
{
bool sol=false;
if(pos>len)
{
if(flag) return true;
return false;
}
if(ch[p][s[pos]-'a'])
if(DFS(pos+1,ch[p][s[pos]-'a'],flag))
return true;
if(!flag)
{
for(int i=0;i<26;i++)
if(s[pos]-'a'!=i&&ch[p][i])
if(DFS(pos+1,ch[p][i],true))
return true;
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%s",s+1);
Insert();
}
for(int i=1;i<=m;i++)
{
scanf("%s",s+1);
len=strlen(s+1);
if(DFS(1,root,false)) printf("YES\n");
else printf("NO\n");
}
return 0;
}
D. R2D2 and Droid Army
题目链接
http://codeforces.com/contest/514/problem/D
题目大意
给你一个
n
行
思路
显然操作
我们可以
O(n−mid+1)
枚举
[L,R]
这段连续的行里全部变为0,显然要想实现这个目标,必须得要做
∑1≤j≤mmaxL≤i≤R{a[i][j]}
次操作,为了快速求出这个值,我们可以建立
m
个线段树,分别维护每一列的区间最大值,然后就是查询线段树后做个求和就好了。
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <cmath>
#define MAXN 110000
#define EPS 1e-10
using namespace std;
int n,m,K;
int mat[MAXN][6];
int maxans,ans[6],sol[6];
struct Segtree
{
int maxv[MAXN<<2];
void Build(int o,int L,int R,int id)
{
if(L==R)
{
maxv[o]=mat[L][id];
return;
}
int M=(L+R)>>1;
Build(o<<1,L,M,id);
Build(o<<1|1,M+1,R,id);
maxv[o]=max(maxv[o<<1],maxv[o<<1|1]);
}
int query(int o,int L,int R,int ql,int qr)
{
if(ql<=L&&R<=qr)
return maxv[o];
int M=(L+R)>>1,ans=0;
if(ql<=M) ans=max(ans,query(o<<1,L,M,ql,qr));
if(qr>M) ans=max(ans,query(o<<1|1,M+1,R,ql,qr));
return ans;
}
}segt[6];
bool check(int len)
{
for(int L=1,R=len;R<=n;L++,R++)
{
int sum=0;
for(int i=1;i<=m;i++)
sol[i]=segt[i].query(1,1,n,L,R);
for(int i=1;i<=m;i++)
sum+=sol[i];
if(sum<=K) return true;
}
return false;
}
int main()
{
scanf("%d%d%d",&n,&m,&K);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&mat[i][j]);
for(int i=1;i<=m;i++)
segt[i].Build(1,1,n,i);
int lowerBound=1,upperBound=n;
maxans=-1;
while(lowerBound<=upperBound)
{
int mid=(lowerBound+upperBound)>>1;
if(check(mid))
{
lowerBound=mid+1;
maxans=mid;
for(int i=1;i<=m;i++) ans[i]=sol[i];
}
else upperBound=mid-1;
}
if(maxans!=-1)
{
for(int i=1;i<=m;i++)
printf("%d ",ans[i]);
printf("\n");
}
else
{
for(int i=1;i<=m;i++)
printf("0 ");
printf("\n");
}
return 0;
}