第一题错了4个,原因是因为用iostream没有取消同步,后来补题,也是很久才发现这点,
我是真的没有想到会卡这点的
TT数鸭子

样例输入
6 5
123456789 9876543210 233 666 1 114514
样例输出
4
解题思路
一开始我用的是set,但是错了4个点,超时
然后补题的时候,我继续用set,并且取消同步,多过了一个点
我想是set太慢了,所以我用了无序的set,结果又多过了一个点
但是这应该是set的极限了
然后我采用数组记录,取消同步后,800ms擦边过的
代码实现
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e6+10;
long long a[N];
int k,n;
bool b[10];
int main()
{
ios::sync_with_stdio(0);
cin>>n>>k;
for(int i=0;i<n;i++) cin>>a[i];
if(k==1){
cout<<0<<endl; return 0;
}
if(k>10){
cout<<n<<endl; return 0;
}
int c;
int sum=0;
int res=0;
for(int i=0;i<n;i++)
{
while(a[i]!=0)
{
c = a[i]%10;
a[i]/=10;
b[c]=1;
}
for(int j=0;j<10;j++)
{
if(b[j]) sum++;
}
if(sum < k) {
res++;
}
sum=0;
memset(b,0,sizeof b);
}
cout<<res<<endl;
return 0;
}
ZJM要抵御宇宙射线
直接爆0,不多bb

解题思路
一开始,我没看到有 一个限制是 : 在点里面选圆心,结果gg了
后来补题的方法是,遍历所有点,算出两两之间的距离的最大值,并存起来
然后从最大值数组里面找出最小的那些
就是我们要的
非常要注意数值的大小
其中距离到最后几个点的时候,是超过了int 的,要用long long
并且输出的时候long long 要用 double
代码实现
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const long long inf = 1e15;
const int N = 1006;
int x,y,n;
int X[N],Y[N];
long long max_dis[N];
struct point{
int x_,y_;
long long dis;
bool operator<(point t){
if(x_!=t.x_) return x_<t.x_;
if(y_!=t.y_) return y_<t.y_;
}
};
point p[N];
int pi;
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%d%d",&X[i],&Y[i]);
// for(int i=0;i<n;i++) printf("%d%d ",X[i],Y[i]);
long long mt,dis;
for(int i=0;i<n;i++)
{
mt = -1;
for(int j=0;j<n;j++)
{
if(i==j) continue;
dis = (long long)(pow(X[i]-X[j],2)+pow(Y[i]-Y[j],2));
if(mt < dis) mt = dis;
}
max_dis[i] = mt;
// printf("%lld ",max_dis[i]);
}
long long min_dis=inf;
for(int i=0;i<n;i++)
{
if(max_dis[i]<min_dis) {
min_dis = max_dis[i];
}
}
for(int i=0;i<n;i++)
{
if(max_dis[i]==min_dis) {
p[pi].x_=X[i],p[pi].y_=Y[i],p[pi].dis=min_dis;pi++;
}
}
sort(p,p+pi);
float xr,yr;
double rr;
xr = (float)(p[0].x_) , yr = (float)(p[0].y_) ,rr = (double)(p[0].dis) ;
printf("%.2f %.2f\n",xr,yr);
printf("%.2lf\n",rr);
return 0;
}
宇宙狗的危机




解题思路
考试的时候,我想暴力出前5个点,但是时间还是不够了
没来得及调试就交了
结果直接编译失败了
之后看了别人的博客才知道这是个dp问题
状态方程 :
dp[i][j][0]: 以i为根,j到i-1为左子树是否可以 (0\1)
dp[i][j][1]: 以i为根,i+1到j为右子树是否可以 (0\1)
转移方程:
dp[j+1][i][0] |=g[j+1][k]
dp[i-1][j][1] |=g[i-1][k]
[i,j]成立,且[i,k],[k,j]都成立,也就是k是根,i 到k-1是左子树,k+1到j是右子树。
往右扩展时,j+1是根,原来的树成了j+1的左子树。
往左扩展,i-1是根,原来的树成了i-1的右子树。
(dp太难了,自己确实写不出来)
代码
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N = 705;
int n,a[N];
bool g[N][N],dp[N][N][2];
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(j==i) continue;
if(gcd(a[i],a[j])>1) g[i][j]=1;
else g[i][j]=0;
}
}
for(int i=1;i<=n;i++) dp[i][i][0]=dp[i][i][1]=1;
for(int j=1;j<=n;j++)
{
for(int i=j;i>=1;i--)
{
for(int k=i;k<=j;k++)
{
if(dp[k][i][0]&&dp[k][j][1]){
dp[j+1][i][0]|=g[j+1][k];
dp[i-1][j][1]|=g[i-1][k];
}
}
}
}
bool flag=0;
for(int i=1;i<=n;i++)
{
if(dp[i][1][0]&&dp[i][n][1]) {flag=1;break;}
}
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
memset(g,0,sizeof g);
memset(dp,0,sizeof dp);
}
return 0;
}
本来以为这次会考得比较好的
结果t1一波超时
t2一波爆0
连t4的前5个点也没混到
直接炸裂
本文分享了作者在算法竞赛中遇到的挑战与解决策略,包括使用不同数据结构优化性能,如set与unordered_set的选择,以及通过动态规划解决复杂问题的经验。
762

被折叠的 条评论
为什么被折叠?



