首页 > 其他分享 >暑假集训CSP提高模拟19

暑假集训CSP提高模拟19

时间:2024-08-12 16:05:06浏览次数:7  
标签:19 ll pos 集训 int ans 510 CSP dis

暑假集训CSP提高模拟19

\(T1\) P173. 数字三角形 \(20pts\)

  • 原题: CF1517C Fillomino 2
  • 部分分
    • \(20pts\) :剪枝搜索。

      点击查看代码
      int p[510],c[510],ans[510][510],dx[5]={0,1,-1,0,0},dy[5]={0,0,0,-1,1};
      void dfs(int pos,int x,int y,int num,int n)
      {
      	if(pos==n+1)
      	{
      		for(int i=1;i<=n;i++)
      		{
      			for(int j=1;j<=i;j++)
      			{
      				cout<<ans[i][j]<<" ";
      			}
      			cout<<endl;
      		}
      		exit(0);
      	}
      	else
      	{
      		if(num==0)
      		{
      			dfs(pos+1,pos+1,pos+1,c[pos+1],n);
      		}
      		else
      		{
      			for(int i=1;i<=4;i++)
      			{
      				int nx=x+dx[i];
      				int ny=y+dy[i];
      				if(1<=nx&&nx<=n&&1<=ny&&ny<=x&&ans[nx][ny]==0)
      				{
      					ans[nx][ny]=p[pos];
      					dfs(pos,nx,ny,num-1,n);
      					ans[nx][ny]=0;
      				}
      			}
      		}
      	}
      }
      int main()
      {
      	int n,i,j;
      	cin>>n;
      	memset(ans,-1,sizeof(ans));
      	for(i=1;i<=n;i++)
      	{
      		cin>>p[i];
      		ans[i][i]=p[i];		
      		c[i]=p[i]-1;
      	}
      	for(i=1;i<=n;i++)
      	{
      		for(j=1;j<=i-1;j++)
      		{
      			ans[i][j]=0;
      		}
      	}
      	dfs(1,1,1,c[1],n);
      	return 0;
      }
      
  • 正解
    • 通过打表,我们可以发现合法方案中同一个数向右延伸一定不优,向左延伸比向下延伸更优。

    • 所以填数时优先向左延伸,否则向下延伸。

      点击查看代码
      int p[510],c[510],ans[510][510];
      void dfs(int pos,int x,int y,int num,int n)
      {
      	if(pos==n+1)
      	{
      		for(int i=1;i<=n;i++)
      		{
      			for(int j=1;j<=i;j++)
      			{
      				cout<<ans[i][j]<<" ";
      			}
      			cout<<endl;
      		}
      		exit(0);
      	}
      	else
      	{
      		if(num==0)
      		{
      			dfs(pos+1,pos+1,pos+1,c[pos+1],n);
      		}
      		else
      		{
      			if(y-1>=1&&ans[x][y-1]==0)
      			{
      				ans[x][y-1]=p[pos];
      				dfs(pos,x,y-1,num-1,n);
      			}
      			else
      			{
      				if(x+1<=n&&ans[x+1][y]==0)
      				{
      					ans[x+1][y]=p[pos];
      					dfs(pos,x+1,y,num-1,n);
      				}
      			}
      		}
      	}
      }
      int main()
      {
      	int n,i;
      	cin>>n;
      	for(i=1;i<=n;i++)
      	{
      		cin>>p[i];
      		ans[i][i]=p[i];		
      		c[i]=p[i]-1;
      	}
      	dfs(1,1,1,c[1],n);
      	return 0;
      }
      

\(T2\) P160. 那一天她离我而去 \(0pts\)

  • 部分分
    • \(76pts\) : \(Dijkstra\) 求解最小环。
      • 枚举 \(1\) 的所有出边,钦定这条边是环上的边,删掉这条边后再求到这个点的最短路长度,加上被删的边的长度与答案取 \(\min\) 即可。

      • 若不限制起点,则需要枚举边 \((u,v,w) \in E\) ,删掉这条边后 \(u \to v\) 的最短路长度 \(+w\) 与答案取 \(\min\) 即可。时间复杂度为 \(O(m(n+m)\log n)\) 。

        点击查看代码
        struct node
        {
        	int nxt,to,w;
        }e[80010];
        int head[10010],vis[10010],dis[10010],brokeu,brokev,cnt=0;
        vector<pair<int,int> >broke;
        void add(int u,int v,int w)
        {
        	cnt++;
        	e[cnt].nxt=head[u];
        	e[cnt].to=v;
        	e[cnt].w=w;
        	head[u]=cnt;
        }
        bool check(int u,int v)
        {
        	return ((u==brokeu&&v==brokev)||(u==brokev&&v==brokeu));
        }
        void dijkstra(int s)
        {
        	memset(dis,0x3f,sizeof(dis));
        	memset(vis,0,sizeof(vis));
        	priority_queue<pair<int,int> >q;
        	dis[s]=0;
        	q.push(make_pair(-dis[s],-s));
        	while(q.empty()==0)
        	{
        		int x=-q.top().second;
        		q.pop();
        		if(vis[x]==0)
        		{
        			vis[x]=1;
        			for(int i=head[x];i!=0;i=e[i].nxt)
        			{
        				if(check(x,e[i].to)==0&&dis[e[i].to]>dis[x]+e[i].w)
        				{
        					dis[e[i].to]=dis[x]+e[i].w;
        					q.push(make_pair(-dis[e[i].to],-e[i].to));
        				}
        			}
        		}
        	}
        }
        int main()
        {
        	int t,n,m,ans,u,v,w,i,j;
        	cin>>t;
        	for(j=1;j<=t;j++)
        	{
        		cnt=0;
        		ans=0x7f7f7f7f;
        		broke.clear();
        		memset(e,0,sizeof(e));
        		memset(head,0,sizeof(head));
        		cin>>n>>m;
        		for(i=1;i<=m;i++)
        		{
        			cin>>u>>v>>w;
        			add(u,v,w);
        			add(v,u,w);
        			if(u==1)
        			{
        				broke.push_back(make_pair(v,w));
        			}
        			if(v==1)
        			{
        				broke.push_back(make_pair(u,w));
        			}
        		}
        		for(i=0;i<broke.size();i++)
        		{
        			brokeu=1;
        			brokev=broke[i].first;
        			dijkstra(1);
        			if(dis[brokev]!=0x3f3f3f3f)
        			{
        				ans=min(ans,dis[brokev]+broke[i].second);
        			}
        		}
        		cout<<(ans>=0x7f7f7f7f?-1:ans)<<endl;
        	}
        	return 0;
        }
        
  • 正解

\(T3\) P175. 哪一天她能重回我身边 \(20pts\)

  • 部分分
    • \(20pts\) :剪枝搜索。

      点击查看代码
      const ll p=998244353;
      ll x[100010],y[100010],cnt[200010],ans,sum;
      void dfs(ll pos,ll num,ll n)
      {
      	if(pos==n+1)
      	{
      		if(num<ans)
      		{
      			ans=num;
      			sum=1;
      		}
      		else
      		{
      			if(num==ans)
      			{
      				sum=(sum+1)%p;
      			}
      		}
      	}
      	else
      	{
      		cnt[x[pos]]++;
      		if(cnt[x[pos]]==1)
      		{
      			dfs(pos+1,num,n);
      		}
      		cnt[x[pos]]--;
      		cnt[y[pos]]++;
      		if(cnt[y[pos]]==1)
      		{
      			dfs(pos+1,num+1,n);
      		}
      		cnt[y[pos]]--;
      	}
      }
      int main()
      {
      	ll t,n,i,j;
      	cin>>t;
      	for(j=1;j<=t;j++)
      	{
      		cin>>n;
      		for(i=1;i<=n;i++)
      		{
      			cin>>x[i]>>y[i];
      		}
      		ans=0x7f7f7f7f;
      		sum=0;
      		dfs(1,0,n);
      		if(ans==0x7f7f7f7f)
      		{
      			cout<<"-1 -1"<<endl;
      		}
      		else
      		{
      			cout<<ans<<" "<<sum<<endl;
      		}
      	}
      	return 0;
      }
      
  • 正解

\(T4\) P174. 单调区间 \(60pts\)

  • 原题: CF1693D Decinc Dividing
  • 部分分
    • \(60pts\) : \(O(n^{2})\) 枚举左右端点,剪枝搜索判断合不合法。

      点击查看代码
      ll a[200010],b[200010];
      vector<ll>s1,s2;
      bool dfs(ll pos,ll n)
      {
      	if(pos==n+1)
      	{
      		return true;
      	}
      	else
      	{
      		ll flag=0;
      		if(s1.size()==0||s1[s1.size()-1]>b[pos])
      		{
      			s1.push_back(b[pos]);
      			flag|=dfs(pos+1,n);
      			s1.pop_back();
      		}
      		if(s2.size()==0||s2[s2.size()-1]<b[pos])
      		{
      			s2.push_back(b[pos]);
      			flag|=dfs(pos+1,n);
      			s2.pop_back();
      		}
      		return flag;
      	}
      }
      bool check(ll l,ll r)
      {
      	for(ll i=l;i<=r;i++)
      	{
      		b[i-l+1]=a[i];
      	}
      	return dfs(1,r-l+1);
      }
      int main()
      {
      	ll n,ans=0,i,j;
      	cin>>n;
      	for(i=1;i<=n;i++)
      	{
      		cin>>a[i];
      	}
      	for(i=1;i<=n;i++)
      	{
      		for(j=i;j<=n;j++)
      		{
      			ans+=check(i,j);
      		}
      	}
      	cout<<ans<<endl;
      	return 0;
      }
      
  • 正解

总结

  • \(T1\) 赛时把结论猜出来后一直在想怎么处理边界和怎么进行 \(hack\) ,到最后也没打代码。
  • \(T2\) 因为提交前忘再编译一遍了,把分号打成了冒号,因 \(CE\) 挂了 \(23pts\) ;因为知道是板子,但自己没学所以干脆没去想 \(Dijkstra\) 怎么求解最小环,可能是学的东西太多了导致的?

后记

标签:19,ll,pos,集训,int,ans,510,CSP,dis
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18355161

相关文章

  • P2014 [CTSC1997] 选课
    题意点击查看题目题目描述在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有\(N\)门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只......
  • CSP真题答案《202309-01、02》基于Python的实现
    注意:注释在测试CSP时应全部删除!!!第一题:#键盘输入两个数以空格隔开,分别为n,mn,m=map(int,input().split())#根据n值可以循环输入n行值,得到一个列表(操作数)madenum=[list(map(int,input().split()))for_inrange(n)]#根据m值可以循环输入m行值,得到一个列表(初始......
  • 0219-使用 TAP 来进行通信
    环境Time2022-11-20WSL-Ubuntu22.04Rust1.65.0pnet0.31.0tun-tap0.1.3前言说明参考:https://docs.rs/pnet_packet/latest/pnet_packet/index.html参考:https://www.kernel.org/doc/html/latest/networking/tuntap.html目标通过TAP来模拟二层设备,接收之前发送的......
  • 8.12信息学集训_摸底
    目录P9955[USACO20DEC]DoYouKnowYourABCs?BP5436【XR-2】缘分P1182数列分段SectionIIP1032[NOIP2002提高组]字串变换P1020[NOIP1999提高组]导弹拦截P1077[NOIP2012普及组]摆花T264125黑暗能量P9955[USACO20DEC]DoYouKnowYourABCs?BP9955[USACO20D......
  • 暑假集训CSP提高模拟18
    好像还有好多没写的A.Mortis赛时思路是正解,但有一个判断想了但出锅了。。。\(n\)个数的序列\(n-1\)次肯定能换完,一次操作最多贡献2,找出贡献2的操作个数减去即可有一次操作匹配两个,两次操作匹配三个,三个操作匹配四个,三种情况,记个数都跑一遍即可点击查看代码#include<bi......
  • [赛记] 暑假集训CSP提高模拟18
    T2T4不太可做,所以没改Mortis20pts原题:Luogu[ABC302G]Sortfrom1to4赛时用$set$乱搞拿了20pts,事实证明确实是乱搞;考虑交换只有三种情况:a在b上,b在a上,需要一次;a在b上,b在c上,c在a上,需要两次;a在b上,b在c上,c在d上,d在a上,需要三次;这里的在什么什么上是指原数组......
  • 2024暑假集训测试22
    前言比赛链接。今天题好难啊,大多数人T2、T4改不动都不改了,下午miaomiao进来和我们说模拟赛改不动的题可以不改。部分分给的也很少。T1Mortis原题:[ABC302G]Sortfrom1to4。\(O(n)\)桶排序,知道每个数最后应该去哪,那么对于需要交换的只有三种情况:二者错排,交换......
  • 2024.8.11 总结(集训 考试)
    之前听说今天的考试难度是NOIP-。T1赛时只会暴力。甚至还想出了比时间复杂度\(O(n^2)\)的暴力更慢的时间\(O(n^3)\)(可能不是,可能要\(/\omega\))的bitset做法。正解之一是xorhashing。前年(T3)、去年(T2?)的CSP-S我都没想出hash做法。感觉自己缺乏想hash的意识。......
  • P9751 [CSP-J 2023] 旅游巴士
    原题链接分析很逆天的一道题设\(dp[i][j]\)为到达第\(i\)个点的时刻\(t\)且满足\(t\modk=j\)的最小\(t\)则有答案为\(dp[n][0]\)更新也很简单,设当前点为\(u\),当前时间为\(t\)需要遍历的下一个点\(v\),则有\(dis[v][(t+1)\%k]=dis[u][t\%k]+1\)如果道路还没开......
  • 1998-2023年上市公司生命周期测算数据(含原始数据+计算代码+结果)
    1998-2023年上市公司生命周期测算数据(含原始数据+计算代码+结果)1、时间:1998-2023年2、来源:上市公司年报、csmar3、指标:证券代码、证券简称、资产总计、净利润、购建固定资产无形资产和其他长期资产支付的现金、营业收入增长率B、股利分配率、行业代码、上市日期、公司成立日......