代码源第一周

这学期不在洛谷做题了,转到代码源了。计划是每周十道题,然而因为这周开始的比较晚,所以只要求做八题。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;
}

以上就是本周的八题了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无用夜宵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值