这学期不在洛谷做题了,转到代码源了。计划是每周十道题,然而因为这周开始的比较晚,所以只要求做八题。ps:题面直接复制过来会有显示bug,所以我就截图粘在这了。可能有点小看不清,点图片放大就好了。
第一题:特殊的正方形
这道题算是热身吧。思路很简单,只要判断每个点在第几圈就行:横向和纵向分别求离最外围最近的距离,然后再把两者比较取更小的那个,就能知道在第几圈了。
代码:
#include<bits/stdc++.h>
using namespace std;
int a[101][101];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
int m1 = min(i, n - i-1), m2 = min(j, n - j-1);
if ((min(m1,m2) + 1) % 2 == 1) a[i][j] = 1;
else if ((min(m1, m2) + 1) % 2 == 0) a[i][j] = 0;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (a[i][j] == 1) cout << "+";
else if(a[i][j]==0) cout << ".";
}
cout << endl;
}
return 0;
}
第二题:走楼梯2
这道题就是斐波那契数列的进阶版本,多了个条件“不能连续三步都走两阶” ,所以这道题要用dp数组。对于dp[i][0]设计为到达第i个台阶,且到达该台阶为从 i-1 台阶走到;对于dp[i][1]设计为到达第i个台阶,且到达该台阶为从 i-2 台阶走到,最近一步走两阶;对于dp[i][2]设计为到达第i个台阶,且到达该台阶为从 i-2 台阶走到,最近两步走两阶。
代码:
#include<bits/stdc++.h>
using namespace std;
long long a[101][101];
int main()
{
long long n, ans;
cin >> n;
a[0][0] = 1;
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= 2; j++)
{
if (j != 2) a[i + 2][j + 1] += a[i][j];
a[i + 1][0] += a[i][j];
}
}
ans = a[n][0] + a[n][1] + a[n][2];
cout << ans;
return 0;
}
第三题:走路
呃……这道题我第一想法是用dfs做,结果给我tle了。
下面是dfs做法,答案没问题
#include <bits/stdc++.h>
using namespace std;
int c[105][2];
int ans[1001000];
int n, m;
void dfs(int a, int b)
{
if (a == n && b <= m)
{
ans[b] = 1;
return;
}
else if (a < n && b <= m)
{
dfs(a + 1, b + c[a + 1][0]);
dfs(a + 1, b + c[a + 1][1]);
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> c[i][0] >> c[i][1];
dfs(0, 0);
for (int i = 0; i <= m; i++) cout << ans[i];
return 0;
}
正确思路应该还是用dp,下面是ac代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100005;
ll f[550][N], a[150], b[150];
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> a[i] >> b[i];
f[0][0] = 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= m; j++)
{
if (f[i][j] == 1 && f[i + 1][j + a[i]] <= m)
f[i + 1][j + a[i]] = 1;
if (f[i][j] == 1 && f[i + 1][j + b[i]] <= m)
f[i + 1][j + b[i]] = 1;
}
}
for (int i = 0; i <= m; i++)
if (f[n][i] == 1)cout << 1;
else cout << 0;
return 0;
}
第四题:简单分数统计
这道题明显的水啊,用几个结构体就完事了。
代码:
#include <bits/stdc++.h>
using namespace std;
int N,M,K;
struct nam
{
char id[505];
long long ans;
}name[101];
struct ti
{
char p[505];
long long sc;
}timu[101];
struct jie
{
char na[505];
char t[505];
char an[10];
}jieguo[101];
int main()
{
cin>>N>>M>>K;
for(int i=0;i<N;i++)
{
cin>>name[i].id;
name[i].ans=0;
}
for(int i=0;i<M;i++) cin>>timu[i].p>>timu[i].sc;
for(int i=0;i<K;i++) cin>>jieguo[i].na>>jieguo[i].t>>jieguo[i].an;
for(int i=0;i<N;i++)
{
for(int j=0;j<K;j++)
{
if(strcmp(name[i].id,jieguo[j].na)==0)
{
for(int n=0;n<M;n++)
{
if(strcmp(jieguo[j].t,timu[n].p)==0)
{
if(jieguo[j].an[0]=='A'&&jieguo[j].an[1]=='C')
name[i].ans+=timu[n].sc;
}
}
}
}
}
for(int i=0;i<N;i++) cout<<name[i].id<<" "<<name[i].ans<<endl;
return 0;
}
第五题:alice的德州扑克
这道题也很水……没什么好说的,只要把各个牌型从上往下依次列出来就行了,反正也不多。
代码:
#include <bits/stdc++.h>
using namespace std;
int a[10];
int b[10];
int main()
{
for(int i=0;i<5;i++)
{
cin>>a[i];
}
for(int i=0;i<5;i++) cin>>b[i];
if(a[0]+1==a[1]&&a[1]+1==a[2]&&a[2]+1==a[3]&&a[3]+1==a[4]&&a[4]==14&&(b[0]==b[1]&&b[1]==b[2]&&b[2]==b[3]&&b[3]==b[4]))
{
cout<<"ROYAL FLUSH";
goto out1;
}
else if(a[0]+1==a[1]&&a[1]+1==a[2]&&a[2]+1==a[3]&&a[3]+1==a[4]&&a[4]!=14&&(b[0]==b[1]&&b[1]==b[2]&&b[2]==b[3]&&b[3]==b[4]))
{
cout<<"STRAIGHT FLUSH";
goto out2;
}
else if((a[0]==a[1]&&a[1]==a[2]&&a[2]==a[3]&&a[3]==a[4])||(a[0]!=a[1]&&a[1]==a[2]&&a[2]==a[3]&&a[3]==a[4])||(a[0]!=a[1]&&a[0]==a[2]&&a[2]==a[3]&&a[3]==a[4])||(a[0]!=a[3]&&a[1]==a[2]&&a[2]==a[0]&&a[2]==a[4])||(a[0]!=a[4]&&a[1]==a[2]&&a[2]==a[3]&&a[3]==a[0]))
{
cout<<"FOUR OF A KIND";
goto out3;
}
else if((a[0]==a[1]&&a[1]==a[2]&&a[2]!=a[3]&&a[3]==a[4])||(a[0]==a[1]&&a[1]==a[3]&&a[0]!=a[2]&&a[2]==a[5])||(a[0]==a[1]&&a[1]==a[4]&&a[0]!=a[3]&&a[3]==a[2])||(a[0]==a[2]&&a[2]==a[3]&&a[0]!=a[1]&&a[1]==a[4])||(a[0]==a[2]&&a[2]==a[4]&&a[2]!=a[3]&&a[3]==a[1])||(a[0]==a[3]&&a[3]==a[4]&&a[0]!=a[1]&&a[1]==a[2])||(a[2]==a[1]&&a[3]==a[2]&&a[2]!=a[0]&&a[0]==a[4])||(a[2]==a[1]&&a[4]==a[2]&&a[2]!=a[3]&&a[3]==a[0])||(a[3]==a[1]&&a[3]==a[4]&&a[1]!=a[0]&&a[0]==a[2])||(a[2]==a[3]&&a[3]==a[4]&&a[2]!=a[0]&&a[0]==a[1]))
{
cout<<"FULL HOUSE";
goto out4;
}
else if(b[0]==b[1]&&b[1]==b[2]&&b[2]==b[3]&&b[3]==b[4])
{
cout<<"FLUSH";
goto out5;
}
else if(a[0]+1==a[1]&&a[1]+1==a[2]&&a[2]+1==a[3]&&a[3]+1==a[4])
{
cout<<"STRAIGHT";
goto out6;
}
else cout<<"FOLD";
out1:
out2:
out3:
out4:
out5:
out6:
return 0;
}
第六题:订单编号
这道题是真难啊,主要是很多这道题需要的知识我都没学,在b站上看了题解还是有点懵懵懂懂。
要用到set的相关操作,erase和auto的操作,还有之前学过的lower_bound 。
代码:
#include <bits/stdc++.h>
using namespace std;
int n;
set<pair<int, int>> c;
inline void insert(int l, int r)
{
if (l > r)
return;
c.insert(make_pair(r, l));
}
int main()
{
cin >> n;
c.insert(make_pair(2e9, 1));
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
auto itr = c.lower_bound(make_pair(x, 0));
if (itr->second <= x)
{
cout << x<<" ";
insert(itr->second, x - 1);
insert(x + 1, itr->first);
c.erase(itr);
}
else
{
cout << itr->second<<" ";
insert(itr->second + 1, itr->first);
c.erase(itr);
}
}
return 0;
}
第七题:饿饿 饭饭
初见这题肯定会想到用队列的方法做吧……如果你是这样想的,那么你就喜提tle了。
我一开始就用的队列, 结果样例只过了两个,其他全都tle了。正确解法要用二分。
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
typedef pair<int, int> PII;
typedef long long LL;
int n;
LL k;
int a[N], c[N];
LL cal(int x)
{
LL res = 0;
for(int i = 1; i <= n; i ++)
{
if(a[i] <= x) res += a[i];
else res += x;
}
return res;
}
int main()
{
LL sum = 0;
scanf("%d%lld", &n, &k);
for(int i = 1; i <= n; i ++)
{
scanf("%d", &a[i]);
sum += a[i];
}
if(sum < (LL)k) puts("-1");
else
{
int l = 0, r = 1e9;
while(l + 1 < r)
{
int mid = l + r >> 1;
if(cal(mid) <= k) l = mid;
else r = mid;
}
k -= cal(l);
int total = 0;
for(int i = 1; i <= n; i ++)
{
if(a[i] > l)
{
c[++ total] = i;
}
}
for(int i = k + 1; i <= total; i ++)
printf("%d ", c[i]);
for(int i = 1; i <= k; i ++)
if(a[c[i]] != l + 1)
printf("%d ", c[i]);
}
return 0;
}
第八题:任务分配
很经典的dp题,我记得以前还做过一模一样的。每个点只有两个状态,那就是选与不选,那转移方程也很清楚了 当i等于开始时间时,f[ei]=max(f[ei],f[si]+wi) 。
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int mod=1e9+7;
const int N=1010;
int f[N];
int a[N],b[N],w[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i]>>w[i];
}
for(int i=1;i<=1000;i++)
{
f[i+1]=max(f[i+1],f[i]);
for(int j=1;j<=n;j++)
{
if(i==a[j])
{
f[b[j]]=max(f[b[j]],f[i]+w[j]);
}
}
}
cout<<f[1000]<<endl;
return 0;
}
以上就是本周的八题了。