校内oj,题目链接就不放了,都是老题,大部分都可以搜到。
A:T1异形卵
签到题:滑动窗口,而且是属于比较简单的那种。
#include<bits/stdc++.h>
using namespace std;
int x[10005];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,l;
cin >> l >> n;
for (int i = 1; i <= n;i++)
{
cin >> x[i];
}
int ans = 0;
for (int i = 1; i <= l;i++)
{
ans += x[i];
}
int max1 = 0, a = 0;
if(ans>max1)
a = 1, max1 = ans;
for (int j = l + 1; j <= n;j++)
{
ans -= x[j - l];
ans += x[j];
if(ans>max1)
{
max1 = ans;
a = j - l + 1;
}
}
cout << a << endl;
}
}
B:外星人的供给站
签到题:只有(-100,100)两百个点,而且最多只有100个数据,暴力完全可以过,怎么都不会被卡。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
using namespace std;
const int maxn = 1e5 + 5;
struct node
{
int x, y;
} e[105];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,r;
cin >> n >> r;
int f[105];
for (int i = 1; i <= n;i++)
{
cin >> e[i].x >> e[i].y;
f[i] = 0;
}
int ans = 0,ans1=0;
while(1)
{
ans1++;
vector<int> q[205];
for (int i = 1; i <= n;i++)
{
if(f[i])
continue;
for (int j = -100; j <= 100;j++)
{
int a;
if(j<0)
{
a = abs(j) + 100;
}
else
a = j;
if((e[i].x-j)*(e[i].x-j)+e[i].y*e[i].y<=r*r)
{
q[a].push_back(i);
}
}
}
int sum = 0, b = 0;
for (int i = 0; i < 201;i++)
{
if(q[i].size()>sum)
{
sum = q[i].size();
b = i;
}
}
ans += q[b].size();
for (int i = 0; i < q[b].size();i++)
{
f[q[b][i]] = 1;
}
if(ans==n)
break;
}
cout << ans1 << endl;
}
}
C:最舒适的路线
题解:我一开始想的是bfs来解决问题,很可惜tle了。正确思路应该是这样,我们首先应该按照边的长度来进行排序,大的在前面,然后从前往后进行遍历,我们还需要并查集来维护s是否可以到达t,这一部分和最小生成树的思想有点像,每次将两个点连接在一块儿,然后每次判断s和t是否在一个块内,如果在一个块内,可得此时是当前这个点最优的情况,然后每次更新即可。
#include<bits/stdc++.h>
using namespace std;
struct node
{
int u, v, w;
} e[5005];
bool cmp(node a,node b)
{
return a.w > b.w;
}
int fa[5005];
int find(int t)
{
if(t==fa[t])
return fa[t];
return fa[t] = find(fa[t]);
}
void merge(int a,int b)
{
a = find(a);
b = find(b);
if(a!=b)
{
fa[a] = b;
}
}
int main()
{
int t;
cin >> t;
while(t--)
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= m;i++)
{
cin >> e[i].u >> e[i].v >> e[i].w;
}
int S, T;
cin >> S >> T;
double l = 1000000.0;
int a, b;
sort(e + 1, e + 1 + m, cmp);
for (int i = 1; i <= m;i++)
{
for (int k = 1; k <= n;k++)
{
fa[k]=k;
}
int k;
for (k = i; k <= m;k++)
{
merge(e[k].u, e[k].v);
if(find(S)==find(T))
break;
}
if(k==m+1)
break;
if(e[i].w*1.0/e[k].w<l)
{
l = e[i].w * 1.0 / e[k].w;
a = e[i].w;
b = e[k].w;
}
}
if(l==1000000.0)
{
cout << "IMPOSSIBLE" << endl;
}
else
{
if(a%b==0)
cout << a / b << endl;
else
{
cout << a /__gcd(a, b) << "/" << b / __gcd(a, b) << endl;
}
}
}
}
D:探 寻 宝 藏
题解:dp,这个题如果让第一次取最大,然后将跑过的改为0,再跑一次,这样是会wa的,我们应该用四维来表示,把每种限定条件表示清楚,这样就可以过题了。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
using namespace std;
int n, m;
int x[55][55];
int dp[55][55][55][55];
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n >> m;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
cin >> x[i][j];
}
}
memset(dp,0,sizeof dp);
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
for (int k = 1; k <= n;k++)
{
for (int l = 1; l <= m;l++)
{
if(i+j!=k+l)
continue;
int tmp = x[i][j] + x[k][l];
if(i==k&&j==l)
tmp -= x[i][j];
dp[i][j][k][l] = max(dp[i][j][k][l], dp[i - 1][j][k - 1][l] + tmp);
dp[i][j][k][l] = max(dp[i][j][k][l], dp[i - 1][j][k][l - 1] + tmp);
dp[i][j][k][l] = max(dp[i][j][k][l], dp[i][j - 1][k - 1][l] + tmp);
dp[i][j][k][l] = max(dp[i][j][k][l], dp[i][j - 1][k][l - 1] + tmp);
}
}
}
}
cout << dp[n][m][n][m] << endl;
}
}
这个题也存在另外三维写法,感兴趣的可以看下代码。
#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
using namespace std;
int n, m;
int x[55][55];
int dp[105][55][55];
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n >> m;
for (int i = 1; i <= n;i++)
{
for (int j = 1; j <= m;j++)
{
cin >> x[i][j];
}
}
int kk = n + m;
memset(dp, 0, sizeof dp);
for (int i = 2; i < kk;i++)
{
for (int j = 1; j <= n;j++)
{
for (int k = 1; k <= n;k++)
{
if(j!=k&&i>=j&&i>=k)
{
dp[i][j][k]=max(dp[i][j][k],max(max(dp[i-1][j-1][k],dp[i-1][j][k-1]),max(dp[i-1][j-1][k-1],dp[i-1][j][k]))+x[j][i-j]+x[k][i-k]);
}
}
}
}
dp[kk][n][n] = max(dp[kk - 1][n][n - 1], dp[kk - 1][n][n - 1]) + x[n][m];
cout << dp[kk][n][n] << endl;
}
}
剩下的待补…