2014蓝桥国赛C组

标题:排列序数

   如果用a b c d这4个字母组成一个串,有4!=24种,如果把它们排个序,每个串都对应一个序号:

  abcd  0

  abdc  1

  acbd  2

  acdb  3

  adbc  4

  adcb  5

  bacd  6

  badc  7

  bcad  8

  bcda  9

  bdac  10

  bdca  11

  cabd  12

  cadb  13

  cbad  14

  cbda  15

  cdab  16

  cdba  17

  ...

    现在有不多于10个两两不同的小写字母,给出它们组成的串,你能求出该串在所有排列中的序号吗?

【输入格式】

一行,一个串。

【输出格式】

一行,一个整数,表示该串在其字母所有排列生成的串中的序号。注意:最小的序号是0。

例如:

输入:

bdca

程序应该输出:

11

再例如:

输入:

cedab

程序应该输出:

70

#include<bits/stdc++.h>
using namespace std;
char s[12],str[12];
int main()
{
	scanf("%s",s);
	int len=strlen(s);
	for(int i=0;i<len;i++)
		str[i]=s[i];
	sort(str,str+len);
	int cnt=0;
	int flag;
	do{
		flag=1;
		for(int i=0;i<len;i++)
		{
			if(s[i]!=str[i])
			{
				flag=0;
				break;
			}
		}
		if(flag)
		{
			printf("%d\n",cnt);
			break;
		}
		cnt++;
	}while(next_permutation(str,str+len));
	return 0;
}

1e5数据 做法:set + 树状数组

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define lowbit(x) x&(-x)
const int N=1e5+10; 
char s[N],str[N],len;
ll f[N];
set<int> st;
int sum[N];
void add(int pos,int val)
{
	while(pos<=len)
	{
		sum[pos]+=val;
		pos+=lowbit(pos);
	}
}
int query(int pos)
{
	int res=0;
	while(pos)
	{
		res+=sum[pos];
		pos-=lowbit(pos);
	}
	return res;
}
int main()
{
	f[0]=1;
	for(int i=1;i<=10;i++)
		f[i]=f[i-1]*i;
	scanf("%s",s);
	len=strlen(s);
	for(int i=0;i<len;i++) str[i]=s[i];
	sort(str,str+len);
	for(int i=0;i<len;i++)
	{
		int pos=lower_bound(str,str+len,s[i])-str;
		s[i]='a'+pos+1;
		st.insert(pos+1);
		add(pos+1,1);
	}
	ll ans=0;
	int cnt;
	for(int i=0;i<len;i++)
	{
		int pos=*st.lower_bound(s[i]-'a');
		cnt=query(pos);
		ans+=(ll)(cnt-1)*f[len-i-1];
		st.erase(pos);
		add(s[i]-'a',-1);
	}
	printf("%lld\n",ans);
	return 0;
}

幂一矩阵:

    atm 不满足幂零矩阵,他自己设想了一个幂一矩阵:对于一个方阵 M ,如果存在一个正整数 k 满足 M^k = I ,其中 I 是单位矩阵,那么 M 就是一个幂一矩阵。

 

    atm 特别钟情于这样一种方阵:每行每列有且仅有一个 1 。经过 atm 不断实验,他发现这种矩阵都是幂一矩阵。

 

    现在,他的问题是,给定一个满足以上条件的方阵,他想求最小的 k 是多少。

 

【输入格式】

第一行一个正整数 n ,表示矩阵大小是 n * n 。

接下来 n 行,每行两个正整数 i j 表示方阵的第 i 行第 j 列为 1。

1 <= i, j <= n 。

行号,列号都从1开始。

 

【输出格式】

一行。一个正整数,即题目中所说最小的 k 。

 

【样例输入】

5

3 1

1 2

4 4

2 3

5 5

 

【样例输出】

3

 

【数据范围】

对于 30% 的数据满足 n <= 10

对于 60% 的数据答案不超过 10^18

对于 100% 的数据满足 n <= 10000

 

求所有到达(i,i)位置次数的最小公倍数

60%:

#include<bits/stdc++.h>
using namespace std;
int v1[10010];
int n;
int main()
{
    scanf("%d",&n);
    int x,y;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        v1[x]=y;
    }
    long long ans=1;
    long long cnt;
    for(int i=1;i<=n;i++)
    {
        cnt=1;
        x=v1[i];
        while(x!=i)
        {
            cnt++;
            x=v1[x];    
        } 
    //  cout<<cnt<<endl;
        ans=ans*cnt/__gcd(ans,cnt);
    }
    cout<<ans<<endl;
    return 0;
}

100%  大数:

#include<bits/stdc++.h>
using namespace std; 
 
#define MAXN 9999
#define MAXSIZE 10
#define DLEN 4
 
class BigNum
{ 
private: 
	int a[500];    //可以控制大数的位数 
	int len;       //大数长度
public: 
	BigNum(){ len = 1;memset(a,0,sizeof(a)); }   //构造函数
	BigNum(const int);       //将一个int类型的变量转化为大数
	BigNum(const char*);     //将一个字符串类型的变量转化为大数
	BigNum(const BigNum &);  //拷贝构造函数
	BigNum &operator=(const BigNum &);   //重载赋值运算符,大数之间进行赋值运算
 
	friend istream& operator>>(istream&,  BigNum&);   //重载输入运算符
	friend ostream& operator<<(ostream&,  BigNum&);   //重载输出运算符
 
	BigNum operator+(const BigNum &) const;   //重载加法运算符,两个大数之间的相加运算 
	BigNum operator-(const BigNum &) const;   //重载减法运算符,两个大数之间的相减运算 
	BigNum operator*(const BigNum &) const;   //重载乘法运算符,两个大数之间的相乘运算 
	BigNum operator/(const int   &) const;    //重载除法运算符,大数对一个整数进行相除运算
 
	BigNum operator^(const int  &) const;    //大数的n次方运算
	int    operator%(const int  &) const;    //大数对一个int类型的变量进行取模运算    
	bool   operator>(const BigNum & T)const;   //大数和另一个大数的大小比较
	bool   operator>(const int & t)const;      //大数和一个int类型的变量的大小比较
	bool   operator==(const BigNum & T)const;  // 大数和大数判断相等
	bool   operator==(const int & t)const;     // 大数和int类型判断相等 
 
	void print();       //输出大数
}; 
BigNum::BigNum(const int b)     //将一个int类型的变量转化为大数
{ 
	int c,d = b;
	len = 0;
	memset(a,0,sizeof(a));
	while(d > MAXN)
	{
		c = d - (d / (MAXN + 1)) * (MAXN + 1); 
		d = d / (MAXN + 1);
		a[len++] = c;
	}
	a[len++] = d;
}
BigNum::BigNum(const char*s)     //将一个字符串类型的变量转化为大数
{
	int t,k,index,l,i;
	memset(a,0,sizeof(a));
	l=strlen(s);   
	len=l/DLEN;
	if(l%DLEN)
		len++;
	index=0;
	for(i=l-1;i>=0;i-=DLEN)
	{
		t=0;
		k=i-DLEN+1;
		if(k<0)
			k=0;
		for(int j=k;j<=i;j++)
			t=t*10+s[j]-'0';
		a[index++]=t;
	}
}
BigNum::BigNum(const BigNum & T) : len(T.len)  //拷贝构造函数
{ 
	int i; 
	memset(a,0,sizeof(a)); 
	for(i = 0 ; i < len ; i++)
		a[i] = T.a[i]; 
} 
BigNum & BigNum::operator=(const BigNum & n)   //重载赋值运算符,大数之间进行赋值运算
{
	int i;
	len = n.len;
	memset(a,0,sizeof(a)); 
	for(i = 0 ; i < len ; i++) 
		a[i] = n.a[i]; 
	return *this; 
}
istream& operator>>(istream & in,  BigNum & b)   //重载输入运算符
{
	char ch[MAXSIZE*4];
	int i = -1;
	in>>ch;
	int l=strlen(ch);
	int count=0,sum=0;
	for(i=l-1;i>=0;)
	{
		sum = 0;
		int t=1;
		for(int j=0;j<4&&i>=0;j++,i--,t*=10)
		{
			sum+=(ch[i]-'0')*t;
		}
		b.a[count]=sum;
		count++;
	}
	b.len =count++;
	return in;
 
}
ostream& operator<<(ostream& out,  BigNum& b)   //重载输出运算符
{
	int i;  
	cout << b.a[b.len - 1]; 
	for(i = b.len - 2 ; i >= 0 ; i--)
	{ 
		cout.width(DLEN); 
		cout.fill('0'); 
		cout << b.a[i]; 
	} 
	return out;
}
 
BigNum BigNum::operator+(const BigNum & T) const   //两个大数之间的相加运算
{
	BigNum t(*this);
	int i,big;      //位数   
	big = T.len > len ? T.len : len; 
	for(i = 0 ; i < big ; i++) 
	{ 
		t.a[i] +=T.a[i]; 
		if(t.a[i] > MAXN) 
		{ 
			t.a[i + 1]++; 
			t.a[i] -=MAXN+1; 
		} 
	} 
	if(t.a[big] != 0)
		t.len = big + 1; 
	else
		t.len = big;   
	return t;
}
BigNum BigNum::operator-(const BigNum & T) const   //两个大数之间的相减运算 
{  
	int i,j,big;
	bool flag;
	BigNum t1,t2;
	if(*this>T)
	{
		t1=*this;
		t2=T;
		flag=0;
	}
	else
	{
		t1=T;
		t2=*this;
		flag=1;
	}
	big=t1.len;
	for(i = 0 ; i < big ; i++)
	{
		if(t1.a[i] < t2.a[i])
		{ 
			j = i + 1; 
			while(t1.a[j] == 0)
				j++; 
			t1.a[j--]--; 
			while(j > i)
				t1.a[j--] += MAXN;
			t1.a[i] += MAXN + 1 - t2.a[i]; 
		} 
		else
			t1.a[i] -= t2.a[i];
	}
	t1.len = big;
	while(t1.a[t1.len - 1] == 0 && t1.len > 1)
	{
		t1.len--; 
		big--;
	}
	if(flag)
		t1.a[big-1]=0-t1.a[big-1];
	return t1; 
} 
 
BigNum BigNum::operator*(const BigNum & T) const   //两个大数之间的相乘运算 
{ 
	BigNum ret; 
	int i,j,up; 
	int temp,temp1;   
	for(i = 0 ; i < len ; i++)
	{ 
		up = 0; 
		for(j = 0 ; j < T.len ; j++)
		{ 
			temp = a[i] * T.a[j] + ret.a[i + j] + up; 
			if(temp > MAXN)
			{ 
				temp1 = temp - temp / (MAXN + 1) * (MAXN + 1); 
				up = temp / (MAXN + 1); 
				ret.a[i + j] = temp1; 
			} 
			else
			{ 
				up = 0; 
				ret.a[i + j] = temp; 
			} 
		} 
		if(up != 0) 
			ret.a[i + j] = up; 
	} 
	ret.len = i + j; 
	while(ret.a[ret.len - 1] == 0 && ret.len > 1)
		ret.len--; 
	return ret; 
} 
BigNum BigNum::operator/(const int & b) const   //大数对一个整数进行相除运算
{ 
	BigNum ret; 
	int i,down = 0;   
	for(i = len - 1 ; i >= 0 ; i--)
	{ 
		ret.a[i] = (a[i] + down * (MAXN + 1)) / b; 
		down = a[i] + down * (MAXN + 1) - ret.a[i] * b; 
	} 
	ret.len = len; 
	while(ret.a[ret.len - 1] == 0 && ret.len > 1)
		ret.len--; 
	return ret; 
}
int BigNum::operator %(const int & b) const    //大数对一个int类型的变量进行取模运算    
{
	int i,d=0;
	for (i = len-1; i>=0; i--)
	{
		d = ((d * (MAXN+1))% b + a[i])% b;  
	}
	return d;
}
BigNum BigNum::operator^(const int & n) const    //大数的n次方运算
{
	BigNum t,ret(1);
	int i;
	if(n<0)
		exit(-1);
	if(n==0)
		return 1;
	if(n==1)
		return *this;
	int m=n;
	while(m>1)
	{
		t=*this;
		for( i=1;i<<1<=m;i<<=1)
		{
			t=t*t;
		}
		m-=i;
		ret=ret*t;
		if(m==1)
			ret=ret*(*this);
	}
	return ret;
}
bool BigNum::operator>(const BigNum & T) const   //大数和另一个大数的大小比较
{ 
	int ln; 
	if(len > T.len)
		return true; 
	else if(len == T.len)
	{ 
		ln = len - 1; 
		while(a[ln] == T.a[ln] && ln >= 0)
			ln--; 
		if(ln >= 0 && a[ln] > T.a[ln])
			return true; 
		else
			return false; 
	} 
	else
		return false; 
}
bool BigNum::operator >(const int & t) const    //大数和一个int类型的变量的大小比较
{
	BigNum b(t);
	return *this>b;
}
bool BigNum::operator==(const BigNum & T) const  //大数和大数判断相等 
{
	if(len != T.len) return false;
	for(int i = 0; i < len; i++)
	{
		if(a[i] != T.a[i])	return false;
	}
	return true;
} 
bool BigNum::operator==(const int & t) const  // 大数和int类型的变量判断相等 
{
	BigNum b(t);
	return *this==b;
}
void BigNum::print()    //输出大数
{ 
	int i;   
	cout << a[len - 1]; 
	for(i = len - 2 ; i >= 0 ; i--)
	{ 
		cout.width(DLEN); 
		cout.fill('0'); 
		cout << a[i]; 
	} 
	cout << endl;
}

int v1[10010];
int n;
int main()
{
//	cout<<1<<endl;
    scanf("%d",&n);
    int x,y;
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        v1[x]=y;
    }
    BigNum ans=1;
    int cnt=1;
    for(int i=1;i<=n;i++)
    {
        cnt=1;
        x=v1[i];
        while(x!=i)
        {
            cnt=cnt+1;
            x=v1[x];    
        }
    	if(ans%cnt != 0)
    	{
    		ans=ans*BigNum(cnt)/__gcd(cnt,ans%cnt);
    	//	cout<<cnt<<endl;
		}
        
    }
    ans.print();
    return 0;
}

标题:重复模式

 

    作为 drd 的好朋友,技术男 atm 在 drd 生日时送给他一个超长字符串 S 。atm 要 drd 在其中找出一个最长的字符串 T ,使得 T 在 S 中至少出现了两次,而他想说的秘密就藏在 T 中。

 

    由于字符串实在是太长了,drd 总是找不到合适的 T 。于是 drd 请你帮他找到这个 T 的长度。

 

【输入格式】

一行。一个字符串,即题目中说的S 。

 

【输出格式】

一行。一个整数,表示最长的 T 的长度。

 

【样例输入】

ababa

 

【样例输出】

3

 

「数据范围」

对于 30% 的数据,S长度 <= 100

对于 60% 的数据,S长度 <= 8000

对于 100% 的数据,S长度 <= 500000

n^4:

#include<bits/stdc++.h>
using namespace std;
string s;
int main()
{
	cin>>s;
	int ans=0;
	int len=s.size();
	for(int i=0;i<len;i++)
	{
		for(int j=1;j<len;j++)
		{
			if(s.find(s.substr(i,j),i+1)!=-1)
				ans=max(ans,j);
			else
				break;
		}
	}
	cout<<ans<<endl;
	return 0;
}

n^3:

//  400
#include<bits/stdc++.h>
using namespace std;
string s;
int nex[1010];
int len;
void getnex(int l,int r)
{
	int i=l,j=-1;
	nex[i]=-1;
	while(i<=r)
	{
		if(j==-1 || s[i]==s[j])
		{
			if(j==-1)
			{
				i++,j=l;
				nex[i]=j;
			}
			else nex[++i]=++j;
		}
		else j=nex[j];
	}
}
int solve(int l,int r,int pos)
{
	int i=l,j=pos;
	while(j<len)
	{
		if(i==-1 || s[i]==s[j])
		{
			if(i==-1) i=l,j++;
			else i++,j++;
		}
		else i=nex[i];
		if(i==r+1) return 1;
	}
	return 0;
}
int main()
{
	cin>>s;
	int ans=0;
	len=s.size();
	for(int i=0;i<len;i++)
	{
		for(int j=i;j<len;j++)
		{
			getnex(i,j);
			if(solve(i,j,i+1)) ans=max(ans,j-i+1);
			else break;
		}
	}
	cout<<ans<<endl;
	return 0;
}

n^2log(n):

// 1000
#include<bits/stdc++.h>
using namespace std;
string s[50010];
string str;
int main()
{
	cin>>str;
	int len=str.size();
	string cnt="";
	for(int i=len-1;i>=0;i--)
	{
		cnt=(char)str[i]+cnt;
		s[i]=cnt;
	}
	sort(s,s+len);
	int ans=0;
	int l;
	for(int i=1;i<len;i++)
	{
		l=min(s[i].size(),s[i-1].size());
		for(int j=0;j<l;j++)
		{
			if(s[i][j]!=s[i-1][j]) break;
			ans=max(j+1,ans);
		}
	}
	cout<<ans<<endl;
	return 0;
}

n^2:

// 10000
#include<bits/stdc++.h>
using namespace std;
int len;
string s;
int main()
{
	cin>>s;
	len=s.size();
	int ans=0;
	int cnt;
	for(int i=1;i<len;i++)
	{
		cnt=0;
		for(int j=i,k=0;j<len;j++,k++)
		{
			if(s[j]==s[k])
			{
				cnt++;
				ans=max(ans,cnt);
			}
			else
			cnt=0;
		}
	}
	cout<<ans<<endl;
	return 0;
}

nlog(n):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
const int N=510000;
int t1[N],t2[N],sum[N],rk[N],ht[N],sa[N],str[N],n;
char s[N];
void get_sa(int n,int m)
{
	int *x=t1,*y=t2;
	for(int i=0;i<m;i++) sum[i]=0;
	for(int i=0;i<n;i++) sum[x[i]=str[i]]++;
	for(int i=1;i<m;i++) sum[i]+=sum[i-1];
	for(int i=n-1;i>=0;i--) sa[--sum[x[i]]]=i;
	for(int p,j=1;p<=n;j<<=1)
	{
		p=0;
		for(int i=n-j;i<n;i++) y[p++]=i;
		for(int i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
		for(int i=0;i<m;i++) sum[i]=0;
		for(int i=0;i<n;i++) sum[x[y[i]]]++;
		for(int i=1;i<m;i++) sum[i]+=sum[i-1];
		for(int i=n-1;i>=0;i--) sa[--sum[x[y[i]]]]=y[i];
		swap(x,y);
		p=1;
		x[sa[0]]=0;
		for(int i=1;i<n;i++) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++;
		if(p>=n) break;
		m=p;
	}
	int k=0;n--;
	for(int i=0;i<=n;i++) rk[sa[i]]=i;
	for(int i=0;i<n;i++)
	{
		if(k)k--;else k=0;
		int j=sa[rk[i]-1];
		while(str[i+k]==str[j+k])k++;
		ht[rk[i]]=k; 
	}
}
int main()
{
	int T;
	char s[500100];
	scanf("%s",s);
	n=strlen(s);
	for(int i=0;i<n;i++) str[i]=s[i];
	str[n]=0;
	get_sa(n+1,256);
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		ans=max(ans,ht[i]);	
	} 
	printf("%d\n",ans);
	return 0;
}

 

标题SpringBoot智能在线预约挂号系统研究AI更换标题第1章引言介绍智能在线预约挂号系统的研究背景、意义、国内外研究现状及论文创新点。1.1研究背景与意义阐述智能在线预约挂号系统对提升医疗服务效率的重要性。1.2国内外研究现状分析国内外智能在线预约挂号系统的研究与应用情况。1.3研究方法及创新点概述本文采用的技术路线、研究方法及主要创新点。第2章相关理论总结智能在线预约挂号系统相关理论,包括系统架构、开发技术等。2.1系统架构设计理论介绍系统架构设计的基本原则和常用方法。2.2SpringBoot开发框架理论阐述SpringBoot框架的特点、优势及其在系统开发中的应用。2.3数据库设计与管理理论介绍数据库设计原则、数据模型及数据库管理系统。2.4网络安全与数据保护理论讨论网络安全威胁、数据保护技术及其在系统中的应用。第3章SpringBoot智能在线预约挂号系统设计详细介绍系统的设计方案,包括功能模块划分、数据库设计等。3.1系统功能模块设计划分系统功能模块,如用户管理、挂号管理、医生排班等。3.2数据库设计与实现设计数据库表结构,确定字段类型、主键及外键关系。3.3用户界面设计设计用户友好的界面,提升用户体验。3.4系统安全设计阐述系统安全策略,包括用户认证、数据加密等。第4章系统实现与测试介绍系统的实现过程,包括编码、测试及优化等。4.1系统编码实现采用SpringBoot框架进行系统编码实现。4.2系统测试方法介绍系统测试的方法、步骤及测试用例设计。4.3系统性能测试与分析对系统进行性能测试,分析测试结果并提出优化建议。4.4系统优化与改进根据测试结果对系统进行优化和改进,提升系统性能。第5章研究结果呈现系统实现后的效果,包括功能实现、性能提升等。5.1系统功能实现效果展示系统各功能模块的实现效果,如挂号成功界面等。5.2系统性能提升效果对比优化前后的系统性能
在金融行业中,对信用风险的判断是核心环节之一,其结果对机构的信贷政策和风险控制策略有直接影响。本文将围绕如何借助机器学习方法,尤其是Sklearn工具包,建立用于判断信用状况的预测系统。文中将涵盖逻辑回归、支持向量机等常见方法,并通过实际操作流程进行说明。 一、机器学习基本概念 机器学习属于人工智能的子领域,其基本理念是通过数据自动学习规律,而非依赖人工设定规则。在信贷分析中,该技术可用于挖掘历史数据中的潜在规律,进而对未来的信用表现进行预测。 二、Sklearn工具包概述 Sklearn(Scikit-learn)是Python语言中广泛使用的机器学习模块,提供多种数据处理和建模功能。它简化了数据清洗、特征提取、模型构建、验证与优化等流程,是数据科学项目中的常用工具。 三、逻辑回归模型 逻辑回归是一种常用于分类任务的线性模型,特别适用于二类问题。在信用评估中,该模型可用于判断借款人是否可能违约。其通过逻辑函数将输出映射为0到1之间的概率值,从而表示违约的可能性。 四、支持向量机模型 支持向量机是一种用于监督学习的算法,适用于数据维度高、样本量小的情况。在信用分析中,该方法能够通过寻找最佳分割面,区分违约与非违约客户。通过选用不同核函数,可应对复杂的非线性关系,提升预测精度。 五、数据预处理步骤 在建模前,需对原始数据进行清理与转换,包括处理缺失值、识别异常点、标准化数值、筛选有效特征等。对于信用评分,常见的输入变量包括收入水平、负债比例、信用历史记录、职业稳定性等。预处理有助于减少噪声干扰,增强模型的适应性。 六、模型构建与验证 借助Sklearn,可以将数据集划分为训练集和测试集,并通过交叉验证调整参数以提升模型性能。常用评估指标包括准确率、召回率、F1值以及AUC-ROC曲线。在处理不平衡数据时,更应关注模型的召回率与特异性。 七、集成学习方法 为提升模型预测能力,可采用集成策略,如结合多个模型的预测结果。这有助于降低单一模型的偏差与方差,增强整体预测的稳定性与准确性。 综上,基于机器学习的信用评估系统可通过Sklearn中的多种算法,结合合理的数据处理与模型优化,实现对借款人信用状况的精准判断。在实际应用中,需持续调整模型以适应市场变化,保障预测结果的长期有效性。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值