"新生赛"长沙理工大学程序设计竞赛(重现赛)

"新生赛"长沙理工大学程序设计竞赛(重现赛)

A

水题,判断1的个数

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
	string str;
	cin >> str;
	int ans = 0;
	for (char ch : str)
	{
		if (ch == '1')
			ans++;
	}
	cout << ans << endl;
	return 0;
}

B

有点像01背包,又有点像多重背包

#include<iostream>
using namespace std;
const int maxn = 1e5+10;
int main()
{
	int n, k, s, x, w=0;
	scanf("%d%d%d", &n,&k,&s);
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &x);
		if (x == s)
			w++;
	}
	long long h[maxn] = { 0 };
	for (int i = 1; i <= k; i++)
		scanf("%lld", &h[i]);
	long long dp[510] = { 0 };
	for (int i = 1; i <= k; i++)
		for (int j = w; j >= i; j--)
			for(int c=1;c*i<=j;c++)
				dp[j] = max(dp[j],  dp[j - c*i] +c* h[i]);
	printf("%lld\n", dp[w]);
	return 0;
}

C

优先保证数字的位数最小,再保证高位尽量小

#include<iostream>
using namespace std;
const int maxn = 1e5+10;
int main()
{
	int n;
	int i, j,flag=0;
	cin >> n;
	for (i = 0; 4 * i <= n; i++)
	{
		for (j = 0; 7 * j <= n - 4 * i; j++)
			if (4 * i + 7 * j == n)
			{
				flag = 1;
				break;
			}
		if (flag)
			break;
	}
	if (!flag)
		cout << "YingYingYing" << endl;
	else
	{
		for (int k = 0; k < i; k++)
			cout << '4';
		for (int k = 0; k < j; k++)
			cout << '7';
	}
	return 0;
}

D

稍微复杂的BFS讨论

#include<iostream>
#include<queue>
#include<map>
#include<math.h>
using namespace std;
char mp[1010][1010] = { 0 };
bool vis[1010][1010] = { false };
int dir[4][2] = { 0,-1,0,1,-1,0,1,0 };
struct Data {
	int x, y;
	bool operator<(const Data& a)const {
		if (x == a.x)
			return y < a.y;
		return x < a.x;
	}
};
int main()
{
	int n, m, x0, y0, ans = -1;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		getchar();
		for (int j = 1; j <= m; j++)
		{
			mp[i][j] = getchar();
			if (mp[i][j] == 'S')
				x0 = i, y0 = j;
		}
	}
	queue < pair<Data, int> > q;
	map<Data, Data>door;
	q.push({ { x0,y0},0 });
	vis[x0][y0] = true;
	int k, x1, y1, step;
	scanf("%d", &k);
	for (int i = 0; i < k; i++)
		scanf("%d%d%d%d", &x0, &y0, &x1, &y1), door[{x0, y0}] = { x1,y1 }, door[{x1, y1}] = { x0,y0 };
	while (!q.empty())
	{
		x0 = q.front().first.x, y0 = q.front().first.y, step = q.front().second;
		q.pop();
		if (mp[x0][y0] == 'T')
			ans = step + (step-1)/8;
		if (door.find({ x0,y0 }) != door.end() && !vis[door[{x0, y0}].x][door[{x0, y0}].y])
		{
			q.push({ {door[{x0,y0}]},step });
			vis[door[{x0, y0}].x][door[{x0, y0}].y] = true;
		}
		for (int i = 0; i < 4; i++)
		{
			if ((mp[x0 + dir[i][0]][y0 + dir[i][1]] != '\0' && mp[x0 + dir[i][0]][y0 + dir[i][1]] != '#') && !vis[x0 + dir[i][0]][y0 + dir[i][1]])
				q.push({ { x0 + dir[i][0],y0 + dir[i][1] },step + 1 }), vis[x0 + dir[i][0]][y0 + dir[i][1]] = true;
		}
	}
	cout << ans << endl;
	return 0;
}

E

栈的简单应用。就是每次右括号进入字符串时前一位必然有左括号与其对应,否则就不符合

#include<iostream>
#include<algorithm>
#include<string>
#include<stack>
using namespace std;
int main()
{
	string str;
	int n;
	cin >> n;
	cin >> str;
	stack<char>st;
	for (char ch:str)
	{
		if (st.empty())
			st.push(ch);
		else
		{
			if (st.top() == '(')
			{
				if (ch == ')')
					st.pop();
				else
					st.push(ch);
			}
			else
				st.push(ch);
		}
	}
	if (st.empty())
		cout << "YES" << endl;
	else
		cout << "NO" << endl;
	return 0;
}

F

并查集模板题

#include<iostream>
#include<algorithm>
#include<string>
#include<stack>
using namespace std;
int father[50010];
int n, m, p;
void init()
{
	for (int i = 1; i <= n; i++)
		father[i] = i;
}
int find_set(int x)
{
	if (x == father[x])
		return x;
	return father[x] = find_set(father[x]);
}
void union_set(int x, int y)
{
	x = find_set(x);
	y = find_set(y);
	father[x] = father[y];
}
int main()
{
	scanf("%d%d%d", &n, &m, &p);
	int u, v;
	init();
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d", &u, &v);
		union_set(u, v);
	}
	for (int i = 0; i < p; i++)
	{
		scanf("%d%d", &u, &v);
		if (find_set(u) == find_set(v))
			printf("Yes\n");
		else
			printf("No\n");
	}
	return 0;
}

G

固定首位为1或者0,分别判断有多少种可能,最后发现其实就是个斐波那契数列

数据范围要是比较大可以使用快速幂求解

#include<iostream>
using namespace std;
const int mod = 1e9 + 7;
int main()
{
	long long  n;
	scanf("%lld", &n);
    int f1=2,f2=3,f;
    if(n==1||n==2)
        cout<<n+2<<endl;
    else
    {
        for(int i=3;i<=n;i++)
        {
            f=(f1+f2)%mod;
            f1=f2;
            f2=f;
        }
        cout<<f<<endl;
    }
	return 0;
}

H

把射击时间转换成子弹到达时间,然后排序,每个时间段的子弹数当前第一次到达的子弹数加上之前已经到达过的子弹数

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int times[maxn],k[2*maxn];
int main()
{
	int n, m, t;
	scanf("%d%d%d", &n, &m, &t);
	for (int i = 0; i < n; i++)
		scanf("%d", &times[i]), times[i] += m;
	sort(times, times + n);
	int l = 0, r = 0;
	while (r < n)
	{
		if (times[r] != times[l])
		{
			k[times[l]] = r;
			l = r;
		}
		else
			r++;
	}
	k[times[l]] =n;
	for (int i = 1; i <= times[l]; i++)
		if (k[i] == 0)
			k[i] = k[i - 1];
	int x;
	while (t--)
	{
		scanf("%d", &x);
		if (x > times[l])
			printf("%d\n", k[times[l]]);
		else
			printf("%d\n", k[x]);
	}
	return 0;
}

I

非常考验细节和理解的BFS

#include<bits/stdc++.h>
using namespace std;
 
struct node1
{
    int x,y,atk;
}monster[25];
struct node2
{
    int x,y,atk;
}pet[2];
struct node3
{
    int x,y,h;
}Q[1000005];
int n,m,atk,L1=0,L2=0,dx[]={0,0,1,-1},dy[]={1,-1,0,0};
char R[1005][1005];
bool V[1005][1005];
int BFS(int sx,int sy,int ex,int ey,long long atk,int preh)
{
    int i,j,d,r=1,f=0,x,y,h,X,Y;
    memset(V,0,sizeof(V));
    V[sx][sy]=1,Q[0].x=sx,Q[0].y=sy,Q[0].h=preh;
    while(r!=f)
    {
        x=Q[f].x,y=Q[f].y,h=Q[f++].h;
        if(x==ex&&y==ey)return h;
        for(i=0;i<4;i++)
        {
            X=x+dx[i],Y=y+dy[i];
            if(X<0||X>=n||Y<0||Y>=m||V[X][Y])continue;
            for(j=0;j<L1;j++)
            {
                d=abs(X-monster[j].x)+abs(Y-monster[j].y);
                if(h+1>=d*2&&atk<=monster[j].atk)break;
            }
            if(j<L1)continue;
            V[X][Y]=1,Q[r].x=X,Q[r].y=Y,Q[r++].h=h+1;
        }
    }
    return -1;
}
int main()
{
    int i,j,a,b,ans1,ans2,sx,sy;
    scanf("%d%d%d",&n,&m,&atk);
    for(i=0;i<n;i++)scanf("%s",R[i]);
    for(i=0;i<n;i++)
        for(j=0;j<m;j++)
        {
            if(R[i][j]=='L')sx=i,sy=j;
            if(R[i][j]=='*')monster[L1].x=i,monster[L1++].y=j;
            if(R[i][j]=='#')pet[L2].x=i,pet[L2++].y=j;
        }
    for(i=0;i<L1;i++)scanf("%d",&monster[i].atk);
    for(i=0;i<L2;i++)scanf("%d",&pet[i].atk);
    if(!L2){printf("0\n");return 0;}
    if(L2==1)
    {
        a=BFS(sx,sy,pet[0].x,pet[0].y,atk,0);
        if(a!=-1)printf("%d\n",a);
        else printf("you die!\n");
        return 0;
    }
    a=BFS(sx,sy,pet[0].x,pet[0].y,atk,0);
    if(a!=-1)b=BFS(pet[0].x,pet[0].y,pet[1].x,pet[1].y,(long long)atk+pet[0].atk,a);
    if(a==-1||b==-1)ans1=-1;
    else ans1=b;
    a=BFS(sx,sy,pet[1].x,pet[1].y,atk,0);
    if(a!=-1)b=BFS(pet[1].x,pet[1].y,pet[0].x,pet[0].y,(long long)atk+pet[1].atk,a);
    if(a==-1||b==-1)ans2=-1;
    else ans2=b;
    if(ans1!=-1&&ans2!=-1)printf("%d\n",min(ans1,ans2));
    else if(ans1==-1&&ans2!=-1)printf("%d\n",ans2);
    else if(ans1!=-1&&ans2==-1)printf("%d\n",ans1);
    else printf("you die!\n");
    return 0;
}

J

看代码大概就明白了

#include<iostream>
using namespace std;
const int maxn = 1e5+10;
int main()
{
	int n, a, b;
	int ans = 0;
	cin >> n >> a >> b;
	while (a != b)
	{
		a = (a + 1) / 2;
		b = (b + 1) / 2;
		ans++;
		n /= 2;
	}
	if (n == 1)
		cout << "Final!" << endl;
	else
		cout << ans << endl;
	return 0;
}

K

数学题,待补

L

待补

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值