24-3-17笔记

整数拼接 

#include<iostream>
#include<string>
using namespace std;
typedef long long LL;
const int N=100010;
int s[11][N];//表示某个数*10^i%k==j的数量
int n;//表示将要输入的n个数
LL a[N];//存放n个数
int k;//表示k倍
LL res;//表示结果
int main()
{
	cin>>n>>k;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	for(int i=0;i<n;i++)
	{
		LL t=a[i]%k;
		for(int j=0;j<11;j++)
		{
			s[j][t]++;//余数为t的方案增加
			printf("s[%d][%d]:%d\n",j,t,s[j][t]);
			t=t*10%k;//a[i]乘j个10的余数
		}
	}
	for(int i=0;i<n;i++)
	{
		LL t=a[i]%k;
		int len=to_string(a[i]).size();//获取a[i]位数
		res+=s[len][(k-t)%k];//(k-t)%k确保得到的余数始终为非负数,并且小于 k
		//找到与a[i]的余数相加能余数为0的方案,len符合
		printf(" %d %d\n",len,(k-t)%k);
		LL r=t;
		while(len--)
		{	
			r=r*10%k;//a[i]乘以自己长度个10的余数
		}
		if(r==(k-t)%k)//去除自己和自己组合的方案
		{
			printf("%d\n",r);
			res--;
		}
	}
	cout<<res<<endl;//4+4-2
	return 0;
}

卡片(模拟)

自写

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(void){
	vector<int> card(10, 2021);
	int num=0;
	for(int i=1;;i++){
		int j=i;
		while(j){
			int x=j%10;
			if(!card[x])goto end;
			else card[x]--;
			j/=10;
		}
		num=i;
	}
	end:cout<<num;
}

直线(数学)

l定义在内部,且用完要清空;保存三个参数的公约数;set和list结构

式子来自

#include<bits/stdc++.h>
using namespace std;
//最大公约数 
inline int gcd(int a, int b) {
    return b == 0 ? a : gcd(b, a % b);
}
//点结构 
struct Node{
	int x;
	int y;
}node[450];
//set
set<list<int> >s; 
int main(void)
{
	int cnt = 0;
	//读入点 
	for(int i = 0; i < 20; i++)
	for(int j = 0; j < 21; j++)
	{
		node[++cnt].x = i;
		node[cnt].y = j;
	}
	//遍历点 
	for(int i = 0; i <= cnt; i++)
    //第二个点没必要从0开始了
	for(int j = i + 1; j <= cnt; j++)
	{
		int x1 = node[i].x, x2 = node[j].x;
		int y1 = node[i].y, y2 = node[j].y;
		//去掉相同点 
		if(x1 == x2 && y1 == y2) continue;
		//系数计算 
		int a = y2 - y1;
		int b = x1 - x2;
		int c = x2 * y1 - x1 * y2;
		int gcdn = gcd(a,gcd(b, c));
		list<int>l;
		l.push_back(a/gcdn);
		l.push_back(b/gcdn);
		l.push_back(c/gcdn);
		s.insert(l);
	}
	cout <<s.size();
	return 0;
}

路径(最短)

思路:建数组(每条路长度,经过与否,总路程长度),从头遍历到尾,距离i最近的点k,有没有别的路从i到k更近

注意点:初始化所有数组,单独初始与起始点有关的数组

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAXN 1e18
//边数组 
ll edge[2025][2025], n = 2021;
//最短路数组,前驱数组 
ll dist[2025], pre[2025];
//标记数组 
bool vis[2025];
void Dijkstra()
{
	//初始化 
	for(int i = 1; i <= n; i++){
		vis[i] = false;
		dist[i] = edge[1][i];
		if(edge[1][i] < MAXN){
			pre[i] = 1;
		}
	}
	//标记 
	vis[1] = true; dist[1] = 0;
	//n-1趟循环 
	for(int i = 1; i < n; i++){
		//找出所有未访问的点中距离起点最近的点 
		int temp;
		ll minn = MAXN;
		for(int j = 1; j <= n; j++){
			if(!vis[j] && dist[j] < minn){
				minn = dist[j];
				temp = j;
			}
		}
		vis[temp] = true;
		//以temp为中间点,刷新起点到各点的最短路径 
		for(int j = 1; j <= n; j++){
			if((dist[temp]+edge[temp][j] < dist[j]) && !vis[j]){
				dist[j] = dist[temp]+edge[temp][j];
				pre[j] = temp;
			}
		}
	}
}
int main(void)
{
	//边权值读入
	 for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(i == j) edge[i][j] = 0;
            else if(abs(i - j) <= 21) edge[i][j] = edge[j][i] = i * j / __gcd(i, j);
            else edge[i][j] = edge[j][i] = MAXN;
        }
    }
	Dijkstra();
	printf("%lld", dist[2021]);
	return 0;
}

砝码问题

比如有abc三物品,依次产生的重量为a,a+b,b,a+b+c,a+c或b+c,c

#include <bits/stdc++.h>
using namespace std;
int w[101], n;
int dp[100010];
int main(void)
{
    //cin
    cin >>n;
    for(int i = 1; i <= n; i++) cin >>w[i];
    memset(dp, 0, sizeof(dp));
    dp[0] = 1;
    
    //第一次01背包(加 | 不加)
    for(int i = 1; i <= n; i++)
    for(int j = 100000; j >= w[i]; j--){
    	dp[j] = max(dp[j], dp[j - w[i]]);//dp[j - w[i]]已经有了方案,才会更新dp[j]
	}
        
    //二次dp(减状态)
    for(int i = 1; i <= n; i++)
    for(int j = 0; j <= 100000 - w[i]; j++)
        dp[j] = max(dp[j], dp[j + w[i]]);
    //结果计数
    long long res = 0;
    for(int i = 0; i <= 100000; i++)
        res += dp[i];
    cout <<res - 1;
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值