1.29(洛谷)

1.P8840

这道题就是依据题目给的条件写,不难。

#include<stdio.h>
int main(void)
{
	int n, a, p, t;
	scanf("%d", &n);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d", &a, &p);
		if(p<16)
		{
			a=a-10;
			if(a<0)
			{
				a=0;
			}
		}
		if(p>20)
		{
			t=p-20;
			a=a-t;
			if(a<0)
			{
				a=0;
			}
		}
		printf("%d\n", a);
	}
	return 0;
}

2.P8822

这道题主要就是每次加费都是人数到达后的下一人开始才加。

#include<stdio.h>
int main(void)
{
	int n, v, m, a, s=0, t;
	scanf("%d%d%d%d", &n, &v, &m, &a);
	//printf("%d %d %d %d %d\n", n, v, m, a, s);
	t=n;
	for(int i=1;i<=t;)
	{
		if(i%m==0)
		{
			s+=v;
			v=v+a;
			//printf("!!%d %d %d %d %d\n", n, v, m, a, s);
			goto end;
		}
		s+=v;
		end:
		i++;
	}
	printf("%d", s);
	return 0;
}

3.P8845

只有在1,2或者2,1时才能满足条件输出Yes其他情况都只输出No。

#include<stdio.h>
int main(void)
{
	int t, x, y;
	scanf("%d", &t);
	for(int i=0;i<t;i++)
	{
		scanf("%d%d", &x, &y);
		if((x==1&&y==2)||(x==2&&y==1))
		{
			printf("Yes\n");
		}
		else
			printf("No\n");
	}
	return 0;
}

4.P8605

这道题我的思路就是去找中间那条路,然后遍历两个点的度数。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 10005
struct Road {
	int u,v;
}road[100005];
int n,m;
ll in[N];
int main()
{
	int i,j,cas=0;
	cin>>n>>m;
	memset(in,0,sizeof(in));
	for(i=1;i<=m;i++) {
		cin>>road[i].u>>road[i].v;
		in[road[i].u]++; in[road[i].v]++;
	}
	ll ret=0;
	for(i=1;i<=m;i++) {
		int u=road[i].u;
		int v=road[i].v;
		ret+=(in[u]-1)*(in[v]-1)*2;
	}
	cout<<ret;	
	return 0;
}

5.P8662

这道题主要就是要注意一种情况:

被淹没之前是一个岛屿,淹没之后却变成了两个岛屿。

#include<bits/stdc++.h>
using namespace std;
int n;
int ans_before;
int ans_after;
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
char pho[1001][1001];
char pho_copy[1001][1001];
void dfs1(int x,int y){
	if(x>n||x<0||y>n||y<0||pho_copy[x][y]!='#'){
		return;
	}
	pho_copy[x][y]='.';
	for(int i=0;i<4;i++){
		int newx=x+dx[i];
		int newy=y+dy[i];
		dfs1(newx,newy);
	}
}
void dfs2(int x,int y){
	if(x>n||x<0||y>n||y<0||pho[x][y]=='.'){
		return;
	}
	pho[x][y]='.';
	for(int i=0;i<4;i++){
		int newx=x+dx[i];
		int newy=y+dy[i];
		dfs2(newx,newy);
		
	}
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			cin>>pho[i][j];
			pho_copy[i][j]=pho[i][j];
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(pho[i][j]=='#'&&(pho[i+1][j]=='.'||pho[i-1][j]=='.'||pho[i][j+1]=='.'||pho[i][j-1]=='.')){
				pho[i][j]='*';
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(pho_copy[i][j]=='#'){
				ans_before++;
				dfs1(i,j);
			}
		}
	}	
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(pho[i][j]=='#'){
				ans_after++;
				dfs2(i,j);
			}
		}
	}	
	cout<<ans_before-ans_after;
	return 0;
}

6.P8802**

这道题是要用到邻接矩阵和dijkstra,朴素版dijkstra就可以了。

#include<bits/stdc++.h>
using namespace std;
const int N=1010;
int gra[N][N];
int dist[N];
int g[N];
bool st[N];
int n,m;
int dijkstra()
{
	memset(dist, 0x3f, sizeof dist);
	dist[1] = 0;
	
	for (int i = 0; i < n - 1; i ++ )
	{
		int t = -1;
		for (int j = 1; j <= n; j ++ )
			if (!st[j] && (t == -1 || dist[t] > dist[j]))
				t = j;
		for (int j = 1; j <= n; j ++ )
			dist[j] = min(dist[j], dist[t] + gra[t][j]);
		st[t] = true;
	}
	return dist[n];
}
int main() 
{
	cin>>n>>m;
	for(int i=1;i<=n;++i) cin>>g[i];
	g[n]=0;
	memset(gra, 0x3f, sizeof gra);
	for(int i=1;i<=m;++i){
		int u,v,c;
		cin>>u>>v>>c;
		gra[u][v]=g[v]+c;
		gra[v][u]=g[u]+c;
	}
	cout<<dijkstra()<<endl;
	return 0;
}

7.P8806**

这道题是一个背包加上贪心的问题,一开始看这道题的时候也没什么思路,还是这种类型的题做少了。

#include<bits/stdc++.h>
using namespace std;
const int N = 1010,M = 20100;
int dp[M];
struct Node
{
	int w,v;
}a[N];
int main()
{
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i].w>>a[i].v;
	sort(a+1,a+n+1,[&](Node A,Node B)
		{
			return A.w+A.v<B.w+B.v;
		});
	memset(dp,-0x3f,sizeof dp);
	dp[0]=0;
	for(int i=1;i<=n;i++)
		for(int j=a[i].w+a[i].v;j>=a[i].w;j--)
			dp[j]=max(dp[j],dp[j-a[i].w]+a[i].v);
	cout<<*max_element(dp,dp+20000)<<endl;
	return 0;
}

8.P8612**

这道题有两种做法:回溯和DP

#include <bits/stdc++.h>
using namespace std;
const int maxn = 52;
const int maxnC = 13;
const int Q = 1000000007;
int dp[maxn][maxn][maxnC][maxnC];
int C[maxn][maxn];
int N, M, K;
int solve()
{
	for (int i = 1; i <= N; i++)
	{
		for (int j = 1; j <= M; j++)
		{
			
			for (int k = 0; k <= K; k++)
			{
				for (int c = 0; c < maxnC; c++)
				{
					if (i == 1 && j == 1)
					{
						if (k == 0 || (k == 1 && c > C[i][j]))
							dp[i][j][k][c] = 1;
						continue;
					}
					int t1 = 0, t2 = 0;
					if (k > 0 && C[i][j] < c)
						t1 = (dp[i][j-1][k-1][C[i][j]] + dp[i-1][j][k-1][C[i][j]]) % Q;
					t2 = (dp[i][j-1][k][c] + dp[i-1][j][k][c]) % Q;
					dp[i][j][k][c] = (t1 + t2) % Q;
				}
			}
		}
	}
	return dp[N][M][K][maxnC-1];
}
int main(){
	scanf("%d%d%d", &N, &M, &K);
	for (int i = 1; i <= N; i++)
		for (int j = 1; j <= M; j++)
			scanf("%d", &C[i][j]);
	printf("%d", solve());
	return 0;
}

9.P8773**

这道题我是没什么思路的,网上看到三种做法:

        线段树、DP、ST表。(待掌握。。。)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int st[100005][20],pos[5000005];
int main()
{
	int n,m,x;cin>>n>>m>>x;
	for(int i=1;i<=n;++i)
	{
		int a;scanf("%d",&a);
		st[i][0]=pos[a^x];
		pos[a]=i;
	}
	int k=log2(n);
	for(int i=1;i<=k;++i)
		for(int j=1;j+(1<<i)-1<=n;++j)
			st[j][i]=max(st[j][i-1],st[j+(1<<(i-1))][i-1]);
	while(m--)
	{
		int l,r;scanf("%d%d",&l,&r);
		int len=log2(r-l+1);
		int p=max(st[l][len],st[r-(1<<len)+1][len]);
		if(p>=l)printf("yes\n");
		else printf("no\n");
	}
}

10.P7493**

这道题,额,对我来说难度有。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值