初三奥赛模拟测试3

初三奥赛模拟测试3

T1 糖果 100pts

T2 魔法仪式 0pts

T3 独特的数组 0pts

T4 约会 0pts

T1 网格图 0pts

  • 正解
    • 先处理出所有连通块及其大小,并记录每个 . 在哪个连通块中。

    • 考虑枚举 k×k 的正方形,将正方形内的所有 . ,在其对应的连通块大小中扣除,然后再枚举正方形外圈的连通块,求它们的大小之和,取 max 即可。

    • 记其右下角为 (x,y) 。考虑右下角由 (x,y1) 变成 (x,y) 时, (i,yk+11) 无法对答案产生贡献, (i,y) 会对答案产生贡献,故可以只枚举这两列从而优化时间复制度。

    • 注意及时消除影响。

      点击查看代码
      int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1},num[250010],pos[510][510],vis[510][510],viss[250010];
      char c[510][510];
      void dfs(int x,int y,int n,int id)
      {
      	vis[x][y]=1;
      	num[id]++;
      	pos[x][y]=id;
      	for(int i=0;i<=3;i++)
      	{
      		if(1<=x+dx[i]&&x+dx[i]<=n&&1<=y+dy[i]&&y+dy[i]<=n&&vis[x+dx[i]][y+dy[i]]==0)
      		{
      			dfs(x+dx[i],y+dy[i],n,id);
      		}
      	}
      }
      int main()
      {
      	int n,m,id=0,sum,ans=0,i,j,k,h;
      	cin>>n>>m;
      	for(i=1;i<=n;i++)
      	{
      		for(j=1;j<=n;j++)
      		{
      			cin>>c[i][j];
      			vis[i][j]=(c[i][j]=='X');
      		}
      	}
      	for(i=1;i<=n;i++)
      	{
      		for(j=1;j<=n;j++)
      		{
      			if(vis[i][j]==0)
      			{
      				id++;
      				dfs(i,j,n,id);
      			}
      		}
      	}
      	for(i=m;i<=n;i++)
      	{
      		for(j=m;j<=n;j++)
      		{
      			if(j==m)
      			{   
      				for(k=i-m+1;k<=i;k++)
      				{
      					for(h=j-m+1;h<=j;h++)
      					{
      						if(c[k][h]=='.')
      						{
      							num[pos[k][h]]--;
      						}
      					}
      				}
      			}
      			else
      			{
      				for(k=i-m+1;k<=i;k++)
      				{
      					h=j-m+1-1;
      					if(c[k][h]=='.')
      					{
      						num[pos[k][h]]++;
      					}
      				}
      				for(k=i-m+1;k<=i;k++)
      				{
      					h=j;
      					if(c[k][h]=='.')
      					{
      						num[pos[k][h]]--;
      					}
      				}
      			}
      			sum=0;
      			if(1<=i-m+1-1)
      			{
      				for(k=j-m+1;k<=j;k++)
      				{
      					sum+=(viss[pos[i-m+1-1][k]]==0)*num[pos[i-m+1-1][k]];
      					viss[pos[i-m+1-1][k]]=1;
      				}
      			}
      			if(i+1<=n)
      			{
      				for(k=j-m+1;k<=j;k++)
      				{
      					sum+=(viss[pos[i+1][k]]==0)*num[pos[i+1][k]];
      					viss[pos[i+1][k]]=1;
      				}
      			}
      			if(1<=j-m+1-1)
      			{
      				for(k=i-m+1;k<=i;k++)
      				{
      					sum+=(viss[pos[k][j-m+1-1]]==0)*num[pos[k][j-m+1-1]];
      					viss[pos[k][j-m+1-1]]=1;
      				}
      			}
      			if(j+1<=n)
      			{
      				for(k=i-m+1;k<=i;k++)
      				{
      					sum+=(viss[pos[k][j+1]]==0)*num[pos[k][j+1]];
      					viss[pos[k][j+1]]=1;
      				}
      			}
      			if(1<=i-m+1-1)
      			{
      				for(k=j-m+1;k<=j;k++)
      				{
      					viss[pos[i-m+1-1][k]]=0;
      				}
      			}
      			if(i+1<=n)
      			{
      				for(k=j-m+1;k<=j;k++)
      				{
      					viss[pos[i+1][k]]=0;
      				}
      			}
      			if(1<=j-m+1-1)
      			{
      				for(k=i-m+1;k<=i;k++)
      				{
      					viss[pos[k][j-m+1-1]]=0;
      				}
      			}
      			if(j+1<=n)
      			{
      				for(k=i-m+1;k<=i;k++)
      				{
      					viss[pos[k][j+1]]=0;
      				}
      			}
      			if(j==n)
      			{
      				for(k=i-m+1;k<=i;k++)
      				{
      					for(h=j-m+1;h<=j;h++)
      					{
      						if(c[k][h]=='.')
      						{
      							num[pos[k][h]]++;
      						}
      					}
      				}
      			}
      			ans=max(ans,sum+m*m);
      		}
      	}
      	cout<<ans<<endl;
      	return 0;
      }
      

T2 序列问题 0pts

  • 正解
    • fi 表示处理到第 i 个数且处理后的序列以 ai 结尾,且 ai 产生了贡献时的最大值,状态转移方程为 fi=maxj=1i1{[aj<ai&&aiajij]×(fj+1)}=maxj=1n{[aj<ai&&jajiai]×(fj+1)}

    • 维护 iai 的最长不降子序列即可。

      点击查看代码
      struct node
      {
          int x,id;
      }a[500010];
      bool cmp(node a,node b)
      {
          return (a.x==b.x)?(a.id>b.id):(a.x<b.x);//注意当x相等时,id要降序排序
      }
      int f[500010];
      int main()
      {
          freopen("sequence.in","r",stdin);
          freopen("sequence.out","w",stdout);
          int n,ans=0,i;
          cin>>n;
          for(i=1;i<=n;i++)
          {
              cin>>a[i].x;
              a[i].id=i;
          }
          sort(a+1,a+1+n,cmp);
          for(i=1;i<=n;i++)
          {
              if(a[i].id-a[i].x>=0)
              {
                  if(a[i].id-a[i].x>=f[ans])
                  {   
                      ans++;
                      f[ans]=a[i].id-a[i].x;
                  }
                  else
                  {
                      f[upper_bound(f+1,f+1+ans,a[i].id-a[i].x)-f]=a[i].id-a[i].x;
                  }
              }
          }
          cout<<ans<<endl;
          fclose(stdin);
          fclose(stdout);
          return 0;
      }
      

T3 置换 0pts

T4 同桌的你 0pts

总结

后记

posted @   hzoi_Shadow  阅读(61)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
扩大
缩小
点击右上角即可分享
微信分享提示