CSP准备

跳一跳

#include <bits/stdc++.h>
using namespace std;
int main()
{
	int a[35];
	int i=0;
	while(cin>>a[i])
	{
		i++;
		if(getchar()=='\n')
		break;
	}
	int s=0;
	int t=2;
	for(int j=0;j<i-1;j++)
	{
		if(a[j]==1)
		s+=1,t=2;
		else
		{
			s+=t;
			t+=2;
		}
	}
	cout<<s<<endl;
	return 0;
}

其实完全可以不全输入,在每一次输入一个时处理就可以,这样写是为了熟悉一下没给出数组长度时的输入方法。

 //方法1:getchar 
//代码通过cin.get()从缓存中读取一个字节,这样就扩充了cin只能用空格和TAB两个作为分隔符。
//这很精巧。发现是’\n’就知道一行结束了 
    vector<int> nums;
    int num;
    while(cin>>num){
        nums.push_back(num);
        if(getchar() == '\n')
            break;
    }
   //方法2:cin.get
    vector<int> nums;
    int num;
    while(cin>>num){
        nums.push_back(num);
        if(cin.get() == '\n')
            break;
    }

寻宝!大冒险!

#include <bits/stdc++.h>
using namespace std;
int a[1001][2],b[51][51];
int temp[51][51]; 
int main()
{
 int n,l,s;
 cin>>n>>l>>s;
 for(int i=1;i<=n;i++)
 {
 	cin>>a[i][0]>>a[i][1];
 }
 for(int i=s;i>=0;i--){//注意行是逆序
 	for(int j=0;j<=s;j++){
 		cin>>b[i][j];
 	}
 }
 int res=0;
 for(int i=1;i<=n;i++)
 {
 	if(a[i][0]+s>l||a[i][1]+s>l) continue;
 	memset(temp,0,sizeof(temp));
 	for(int j=1;j<=n;j++)
 	{
 		int dx=a[j][0]-a[i][0];
 		int dy=a[j][1]-a[i][1];
 		if(dx<=s&&dy<=s&&dx>=0&&dy>=0)
 		temp[dx][dy]=1;
 	}
 	bool success=true; 
 	for(int x=0;x<=s;x++){		
 		for(int y=0;y<=s;y++){
 			if(temp[x][y]!=b[x][y]){
 				success=false;
 				break;
 			}
 			if(!success)break;
 		}
 	
  }if (success)res++;  }
cout<<res;
 return 0;
}

训练计划

#include <bits/stdc++.h>
using namespace std;

const int N = 101;
int n, m;
int p[N], t[N];
int earl[N], late[N];

int main()
{
  cin>>n>>m;
  int f=1;
  for(int i=1;i<=m;i++)
  {
  	cin>>p[i];
  	}	
  for(int i=1;i<=m;i++)
  {
  	cin>>t[i];
  	}
  for(int i=1;i<=m;i++)
  {
  	if(p[i]==0)
  	{
  		earl[i]=1;
  	}else
  	{
  		earl[i]=earl[p[i]]+t[p[i]];
  	}
  	if(earl[i]+t[i]-1>n)
  	f=0;
  }
  for(int i=1;i<=m;i++)
  	{
  		cout<<earl[i]<<" ";
  	}
  if(f!=0){
  
  //应该是所有依赖该科目的科目中最早开始的那个就是该科目的最晚结束时间 
  	memset(late,0x3f,sizeof(late));
  	cout<<endl;
  	for(int i=m;i>0;i--)
  	{
  		if(late[i]==0x3f3f3f3f)
  		late[i]=n-t[i]+1;
  		late[p[i]]=min(late[p[i]],late[i]-t[p[i]]);
  	}
  	for(int i=1;i<=m;i++)
  	cout<<late[i]<<" ";
  }
  return 0;
}

另一种正序的写法

if (f== 1) {
        // 将确定每个科目的最晚,从最后的科目往前推,需要把依赖该科目的科目所消耗时间算上
        for (int i = m; i >= 1; i--) {
            int temp = 366;
            for (int j = i + 1; j <= m; j++) {
                // 寻找是否有依赖该科目的科目
                if (p[j] == i)
                    temp = min(temp, latest[j]);
            } 
            // 如果没有被依赖,那么最晚开始时间 = 最后期限 - 持续时间的时刻
            if (temp == 366)
                latest[i] = n - t[i] + 1;
            // 如果有被依赖,那么最晚开始时间 = 依赖它的科目的最晚开始的时刻最小的科目 - 本身的持续时间的时刻
            else
                latest[i] = temp - t[i];
        }
        // 输出每项科目的最晚开始时间
        for (int i = 1; i <= m; i++)
            cout << latest[i] << " ";
    }
    ```
    # 何以包邮
    ```
    #include <bits/stdc++.h>
using namespace std;

int n, x;
int v[40] = { 0 };
int f[40][10010] = { {0} };

int main()
{
	cin>>n>>x;
	int sum=0;
	for (int i = 1; i <= n; i++) {
		cin >> v[i];
		sum += v[i];
	}
	int y=sum-x;
	for(int i=1;i<=n;i++)
	for(int j=y;j>0;j--)
	{
		f[i][j]=f[i-1][j];
		if(j>=v[i])f[i][j]=max(f[i][j],f[i-1][j-v[i]]+v[i]);
	}
	int r=sum-f[n][y];
	cout<<r<<endl;
	
	return 0;
}

角色授权

#include<bits/stdc++.h>
using namespace std;
 
class role{
	public:
		set<string> opl;
		set<string> opt;
		set<string> opn;
};
 
class group{
	public:
		set<string> rol;
};
 
map<string,role> mpr;
map<string,group> mpg;
 
class user{
	public:
		set<string> rol;
		set<string> grp;
		
		bool check(string opl,string opt,string opn){
			for(auto it:rol)
				if(mpr[it].opl.count("*") || mpr[it].opl.count(opl))
					if(mpr[it].opt.count("*") || mpr[it].opt.count(opt))
						if(mpr[it].opn.empty() || mpr[it].opn.count(opn))
							return true;
			
			for(auto it:grp)
				if(mpg.count(it))
					for(auto it1:mpg[it].rol)
						if(mpr[it1].opl.count("*") || mpr[it1].opl.count(opl))
							if(mpr[it1].opt.count("*") || mpr[it1].opt.count(opt))
								if(mpr[it1].opn.empty() || mpr[it1].opn.count(opn))
									return true;
			return false;
		}
		
};
map<string,user> mpu;
 
signed main(){
	//提高cin,cout的速度 
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	 
	int n,m,q,nv,no,nn,k;
	string name,rname,uname,x,y,z,ch;
	cin>>n>>m>>q;
	
	for(int i=0;i<n;i++){
		cin>>name>>nv;
		while(nv--)
			cin>>x,mpr[name].opl.emplace(x);
		cin>>no;
		while(no--)
			cin>>x,mpr[name].opt.emplace(x);
		cin>>nn;
		while(nn--)
			cin>>x,mpr[name].opn.emplace(x);
	}
	
	for(int i=0;i<m;i++){
		cin>>rname>>k;
		for(int j=0;j<k;j++){
			cin>>ch>>name;
			if(ch == "g")
				mpg[name].rol.emplace(rname);
			else
				mpu[name].rol.emplace(rname);
		}
	}
	
	for(int i=0;i<q;i++){
		cin>>uname>>k;
		for(int j=0;j<k;j++)
			cin>>name,mpu[uname].grp.emplace(name);
		cin>>x>>y>>z;
		cout<<mpu[uname].check(x,y,z)<<endl;
		mpu[uname].grp.clear();
	}
	 
}

出行计划

  • 70分
#include<bits/stdc++.h>
using namespace std;

int n,m,k;
const int N=2e5+2; 
int q,t[N],c[N];
int main()
{
	cin>>n>>m>>k;
	for(int i=0;i<n;i++)
	{
		cin>>t[i]>>c[i];
	}
	for(int i=0;i<m;i++)
	{
		cin>>q;
		int sum=0;
		for(int j=0;j<n;j++)
		{
			if(q+k<=t[j]&&t[j]<q+k+c[j])
			sum++;
		}
		cout<<sum<<endl;
		
	}
return 0;
}
  • 100分 差分
#include<bits/stdc++.h>
using namespace std;

int n,m,k;
const int N=2e5+2; 
int q,t[N],c[N],s[N];
int t1,c1;
int main()
{
	cin>>n>>m>>k;
	for(int i=0;i<n;i++)
	{
		cin>>t1>>c1;
		int l=max(0,t1-c1+1-k);
		int r=max(0,t1-k);
		s[l]++;
		s[r+1]--;
	}
	for(int i=0;i<N;i++)
	s[i]+=s[i-1];
	for(int i=0;i<m;i++)
	{
		cin>>q;
		cout<<s[q]<<endl;
	}
return 0;
}

序列查询

可以直接加,但是上面刚用完差分再练习一下差分吧

#include<bits/stdc++.h>
using namespace std;
const int M=1e7+2;
int n,N
int s[M];
int a;
int main()
{
	cin>>n>>N;
	for(int i=0;i<n;i++)
	{
		cin>>a;
		s[a]++;
	}
	for(int i=1;i<N;i++)
	{
		s[i]+=s[i-1]; 
	}
	int sum=0;
	for(int i=0;i<N;i++)
	{
		s[i+1]+=s[i]; 
	}
	cout<<s[N];
return 0;
}

序列查询新解

#include<bits/stdc++.h>
using namespace std;
const int M=1e7+2;
int n,N
int s[M];
int a;
int main()
{
	cin>>n>>N;
	int r=N/(n+1);
	for(int i=0;i<n;i++)
	{
		cin>>a;
		s[a]++;
	}
	for(int i=1;i<N;i++)
	{
		s[i]+=s[i-1]; 
	}
	int sum=0;
//	for(int i=0;i<N;i++)
//	{
//		s[i+1]+=s[i]; 
//	}
//	cout<<s[N];
	for(int i=0;i<N;i++)
	{
		sum+=abs(i/r-s[i]);
	}
	cout<<sum;
return 0;
}

神经脉冲网络

#include<iostream>
#include<vector>
using namespace std;
static unsigned long Next = 1;//题目的next要改一下,不然会报错 
/* RAND_MAX assumed to be 32767 */
int myrand(void) 
{
    Next = Next * 1103515245 + 12345;
    return((unsigned)(Next/65536) % 32768);
}
struct edg//突触结构体 
{
	int end;
	double w;
	int D;
};
double v[1001];//神经元的状态参数,v,u,a,b,c,d 
double u[1001];
double a[1001], b[1001], c[1001], d[1001]; 
int r[1001]={0};//脉冲源的r参数 
vector<edg>e[2001];//突触,下标为起始发送源,存储的是该发送源能到达的目标神经元 
double ik[1001][1001]={0};//行为时间点,列为目标神经元 
int sum[1001]={0};//神经元的发送次数 
int main()
{
	int n=0, s=0, p=0, T=0;
	scanf("%d%d%d%d", &n, &s, &p, &T);
	double dt=0.0;
	scanf("%lf", &dt);
	int sum_n=0, rn=0, g=0;
	while(sum_n<n)//输入神经元 
	{
		scanf("%d%lf%lf%lf%lf%lf%lf", &rn, &v[g], &u[g], &a[g], &b[g], &c[g], &d[g]);
		g++;
		for(int i=1; i<rn; i++)
		{
			v[g]=v[g-1];
			u[g]=u[g-1];
			a[g]=a[g-1];
			b[g]=b[g-1];
			c[g]=c[g-1];
			d[g]=d[g-1];
			g++;
		}
		sum_n=sum_n+rn;
	}
	for(int i=0; i<p; i++)//输入脉冲源 
	{
		scanf("%d", &r[i]);
	}
	for(int i=0; i<s; i++)//输入突触 
	{
		edg p;
		int start=0;
		scanf("%d%d%lf%d", &start, &p.end, &p.w, &p.D);
		e[start].push_back(p);
	}
	//开始模拟 
	for(int t=1; t<=T; t++)
	{
		int temp_t=t%1000;//T最大为1000,后面的时刻可以把前面用过的t给覆盖掉 
		for(int i=0; i<n; i++)//神经元遍历 
		{
			double v_pre=v[i];
			v[i]=v[i]+dt*(0.04*v[i]*v[i]+5*v[i]+140-u[i])+ik[temp_t][i];
			ik[temp_t][i]=0;//用完之后清零,防止%1000的时候再次读到前面的脉冲 
			u[i]=u[i]+dt*a[i]*(b[i]*v_pre-u[i]);
			if(v[i]>=30)
			{
				sum[i]++;
				v[i]=c[i];
				u[i]=u[i]+d[i];
				for(int j=0; j<e[i].size(); j++)
				{
					ik[(t+e[i][j].D)%1000][e[i][j].end]+=e[i][j].w;
				}	
			}
		}
		for(int i=0; i<p; i++)//脉冲源遍历 
		{
			if(r[i]>myrand())
			{
				for(int j=0; j<e[i+n].size(); j++)
				{
					//脉冲源的编号是在神经元之后,即(i+n)
					ik[(t+e[i+n][j].D)%1000][e[i+n][j].end]+=e[i+n][j].w;
				}		
			}
		}
	}
	double v_min=v[0], v_max=v[0];
	int sum_min=sum[0], sum_max=sum[0];
	for(int i=1; i<n; i++)
	{
		if(v_min>v[i])v_min=v[i];
		if(v_max<v[i])v_max=v[i];
		if(sum_min>sum[i])sum_min=sum[i];
		if(sum_max<sum[i])sum_max=sum[i];
	}
	printf("%.3lf %.3lf\n%d %d", v_min, v_max, sum_min, sum_max);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值