"新生赛"长沙理工大学程序设计竞赛(重现赛)
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", ×[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;
}