集训第一周解题报告

在第一场组队赛中,解出了两道题目A和B,涉及简单搜索和经典模型的模拟。赛后独立解决了C题,目前正致力于攻克G题。A题是一个关于寻找解的数量的问题,通过深度优先搜索解决,不需要复杂的标记过程。分析发现,蚂蚁行走过程中只需调整某些蚂蚁的方向即可确保所有蚂蚁离开,这涉及到最长上升子序列的理解和应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一场组队赛里只A了两题A和B,一道简单搜索一道经典模型的模拟题。

赛后过了C,正在努力做G。

A题:

给出一个数s要求找出用k个不同且小与等于n的数组成s的解的个数,简单DFS,从小到大搜索,标记数组都不需要。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 100005
#define eps 1e-7
#define INF 0x7FFFFFFF
#define ff sqrt(5.0)
typedef long long ll;

int n,k,s;
int ans;
void dfs(int aa,int p,int sum){
    if(p==k){
        if(sum==s){
            ans++;
        }
        return ;
    }
    if(p>k) return ;
    if(sum>s)   return ;
    for(int i=aa+1;i<=n;i++)
	{
 		dfs(i,p+1,sum+i);
    }
}
int main(){
    int i,j;
    while(scanf("%d%d%d",&n,&k,&s)!=EOF){
        if(n==0||k==0||s==0)    break;
        ans = 0;
        for(int i=1;i<=n;i++){
            dfs(i,1,i);
        }
        printf("%d\n",ans);
    }
    return 0;
}
B题模拟,蚂蚁碰头。

仔细分析后可以看出来,相距为1切面对面的蚂蚁只会交错过去,因此只需要每次走1s的距离,在最后判断位置重叠方向相反的蚂蚁,让其掉头,直至所有蚂蚁走出去。

#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 100005
#define eps 1e-7
#define INF 0x7FFFFFFF
#define ff sqrt(5.0)
typedef long long ll;

struct node{
    int num,pos;
    char dir;
}a[25];
bool cmp(node x,node y){
    return x.pos<y.pos;
}
int main(){
    int l,n,i;
    int cnt,ans;
    while(scanf("%d%d",&n,&l)!=EOF){
        if(n==0&&l==0)  break;
        cnt = ans = 0;
        for(i=0;i<n;i++){
            getchar();
            cin>>a[i].dir>>a[i].pos;
            a[i].num = i+1;
        }
        sort(a,a+n,cmp);
        node ant[2];
        int flag;
        while(1){
            cnt++;
            flag = 0;
            for(i=0;i<n;i++){
                if(a[i].pos<=0||a[i].pos>=l)    continue;
                if(a[i].dir=='R')   a[i].pos++;
                else    a[i].pos--;
                if(a[i].pos==0||a[i].pos==l){
                    ant[flag] = a[i];
                    flag++;
                }
            }
            sort(a,a+n,cmp);
            for(i=0;i<n-1;i++){
                if(a[i].pos==a[i+1].pos){
                    if(a[i].dir=='L')   a[i].dir = 'R';
                    else    a[i].dir = 'L';
                    if(a[i+1].dir=='L')   a[i+1].dir = 'R';
                    else    a[i+1].dir = 'L';
                }
            }
            int ccc = 0;
            for(i=0;i<n;i++){
                if(a[i].pos<=0||a[i].pos>=l)    ccc++;
            }
            if(ccc==n)  break;
        }
        if(flag==1) ans = ant[0].num;
        else{
            if(ant[0].dir=='L') ans = ant[0].num;
            else    ans = ant[1].num;
        }
        cout<<cnt<<" "<<ans<<endl;
    }
    return 0;
}

C题

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
struct node
{
	int a,b,c,d;
}rec[10000];
int x[1200],y[1200];
int tx[1100000],ty[1100000];
int mp[1200][1200],n;
int lx,ly;
void init()
{
	for(int i=0;i<n;i++)
	{
		int A=tx[rec[i].a];
		int B=ty[rec[i].b];
		int C=tx[rec[i].c];
		int D=ty[rec[i].d];
		for(int j=A;j<=C;j++)
		{
			mp[j][D]=mp[j][B]=1;
		}
		for(int j=D;j<=B;j++)
		{
			mp[A][j]=mp[C][j]=1;
		}
	}
}
int dir[4][2]={{0,-1},{0,1},{1,0},{-1,0}};
bool in(int x,int y)
{
	return (x >= 1 && y >= 1 && x <= 2 * lx - 2 && y <= 2 * ly - 2);
}
void dfs(int x,int y)
{
	mp[x][y]=1;
	for(int i=0;i<4;i++)
	{
		int xx=x+dir[i][0];
		int yy=y+dir[i][1];
		if(in(xx,yy)&&(!mp[xx][yy]))
		{
			dfs(xx,yy);
		}
	}
}
int main()
{
	while(scanf("%d",&n)!=EOF&&n)
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d%d%d%d",&rec[i].a,&rec[i].b,&rec[i].c,&rec[i].d);
			x[2 * i] = rec[i].a;
            x[2 * i + 1] = rec[i].c;
            y[2 * i] = rec[i].b;
            y[2 * i + 1] = rec[i].d;
		}
		sort(x, x + 2 * n);
        sort(y, y + 2 * n);
        lx = unique(x, x + 2 * n) - x;
        ly = unique(y, y + 2 * n) - y;
        for (int i = 0; i < lx; i++)
        {
            tx[x[i]] = 2 * i;
        }
        for (int j = 0; j < ly; j++)
        {
            ty[y[j]] = 2 * j;
        }
        memset(mp, 0, sizeof(mp));
        init();
        for (int i = 0; i < 2 * lx; i++) if (mp[i][0] == 0)
		{
            dfs(i, 0);
        }
        for (int i = 0; i < 2 * lx; i++) if (mp[i][2 * ly - 1] == 0)
		{
            dfs(i, 2 * ly - 1);
        }
        for (int i = 0; i < 2 * ly; i++) if (mp[0][i] == 0)
		{
            dfs(0, i);
        }
        for (int i = 0; i < 2 * ly; i++) if (mp[2 * lx - 1][i] == 0)
		{
            dfs(2 * lx - 1, i);
        }
        int ans= 1;
        for (int i = 1; i < 2 * lx - 1; i++)
	 	{
            for (int j = 1; j < 2 * ly - 1; j++) if (mp[i][j] == 0)
			{
                dfs(i, j);
                ans++;
            }
        }
        cout<<ans<<endl;
	}
	return 0;
}

G题:比赛中和B题双开的,还没出,正在学习。

最长上升子序列学习中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值