检查每只鸭子映射成的数,用一个元素数为符号数(10)的布尔数组记录出现过的数符,累加得到该数中的数符种类然后判断是否小于k。
#include
#include
using namespace std;
int n,k;
long long cot[15];
char str[20];
int ans;
void clean(){
for(int i=0;i<=9;i++)cot[i]=0;
}
int main(){
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++){
clean();
scanf("%s",str);
int len=strlen(str);
for(int i=0;i<len;i++)
cot[str[i]-'0']++;
int temp=0;
for(int i=0;i<=9;i++)
if(cot[i]!=0)temp++;
if(temp<k)ans++;
}
printf("%d\n",ans);
}
本题并不用找最小圆覆盖,只要暴力检查所有点即可,可在O(n2)内完成。
维护一个全局最小值GlobalMin
和局部最大值PartMax
。对于每个点,检查它与其他所有点之间距离的平方,并将最大值记录在PartMax
中,检查完后与GlobalMin
比较,取较小值并相应更新选择的点。最终答案即GlobalMin
与其对应的中心点。
本题爆了一个点,因为最大值算错了一个常数,开的大小不足。
本题要求距离的平方,结果保留两位小数,而坐标都是整数,所以取巧直接格式输出"%lld.00
"。
#include
#include
#define MAX 100000000000//最大值开错了一个常数级
using namespace std;
struct point{
long long x,y;
bool operator<(const point& p)const{
if(x!=p.x)return x<p.x;
return y<p.y;
}
};
long long dist2(point a,point b){
long long x2=(b.x-a.x)*(b.x-a.x);
long long y2=(b.y-a.y)*(b.y-a.y);
return x2+y2;
}
int N;
point P[1005];
long long GlobalMin,PartMax;
int grcd;
int main(){
scanf("%d",&N);
//cin>>N;
for(int i=1;i<=N;i++){
long long x,y;
scanf("%lld %lld",&x,&y);
P[i].x=x;
P[i].y=y;
}
sort(P+1,P+N+1);
GlobalMin=MAX;
for(int i=1;i<=N;i++){
PartMax=0;
for(int j=1;j<=N;j++){
if(j!=i){
long long temp=dist2(P[i],P[j]);
if(temp>PartMax)PartMax=temp;
}
}
if(PartMax<GlobalMin){
GlobalMin=PartMax;
grcd=i;
}
}
printf("%lld.00 %lld.00\n%lld.00\n",P[grcd].x,P[grcd].y,GlobalMin);
}
本题运用动态规划。
定义状态L[i][j]
和R[i][j]
,分别表示"[j,i-1]能成为i的左子树
"、"[i+1,j]能成为i的右子树
"。预处理二维数组E[i][j]
表示"gcd(a[i],a[j])>1
"。
状态转移过程如下:对每一个区间[i,j],检查向左[i-1,j]扩展和向右[i,j+1]扩展,方法是检查区间[i,j]中是否存在节点k,满足L[i,k]&&R[k,j]&&E[i-1][k]
或L[i,k]&&R[k,j]&&E[j+1][k]
。遍历所有的区间[i,j],获得全部的L[i][j]和R[i][j],最后检查是否存在L[k][1]&&R[k][n]==1
,若存在即Yes。
课堂测试中其实没有看出来这是一道dp题,用了一种错误的贪心做法:
对于每一个要添加的节点,首先检查其与当前树最大节点的gcd是否大于1,若是则直接插入,否则从根节点开始沿右子检查,找到第一个与要添加节点的gcd大于1的节点,因为其必无左子,将父节点作为左子插入,将自身作为新节点的右子插入,重构搜索树。
后来找到一个反例:在此类情况下,搜索树存在,但该做法不能实现
(17×29不能紧随13×23插入,结果为No)
#include
#include
using namespace std;
int t,n,a[705];
bool JDG;
bool E[705][705];
bool L[705][705],R[705][705];
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int main(){
cin>>t;
while(t--){
memset(L,0,sizeof(L));
memset(R,0,sizeof(R));
JDG=0;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
E[i][i]=0;
L[i][i]=R[i][i]=1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i!=j){
if(gcd(a[i],a[j])>1)E[i][j]=1;
else E[i][j]=0;
}
}
}
for(int i=1;i<=n;i++){
for(int j=i;j>=1;j--){
for(int k=j;k<=i;k++){
if(L[k][j]&&R[k][i]){
if(E[i+1][k])L[i+1][j]=1;
if(E[j-1][k])R[j-1][i]=1;
}
}
}
}
for(int i=1;i<=n;i++){
if(L[i][1]&&R[i][n]){
JDG=1;
break;
}
}
if(JDG)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}