洛谷 传智杯

传智杯:
没ak。。。

A 软工实习

题目链接

题意:看题易知

解题思路:
sort排序每一列,即每一组队伍的评分。然后每一列不合格数值剔除,然后再计算每个人,再sort排序。注意,分数相同按照字母序小的在前面,还有四舍五入,函数用round。

代码:

#include
#define sc(x) scanf("%lld",&x);
#define pf printf
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define dep(i,e,s) for(int i=e;i>=s;i--)
using namespace std;
typedef long long ll;
const int maxn=1e4+7;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
double b[30][30];
struct node{
	double x;
	char c;
};
node a[maxn];
node ans[maxn];
double sum[30],ave[30];
int cnt[30];
bool cmp(node a,node b)
{
	if(a.x!=b.x)
		return a.x>b.x;
	else
		return a.c<b.c;
}
int main()
{
	SIS;
	//¼ÓËÙcin/cout
	int n,m;
	cin>>n>>m;
	double x;
	char c;
	for(int i=1;i<=n;i++)
	{
		cin>>x>>c;
		a[i].x=x;
		a[i].c=c;
	}
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=m;j++)
			cin>>b[i][j];
	}
	for(int j=1;j<=m;j++)
	{
		for(int i=1;i<=m;i++)
			sum[j] = sum[j]+b[i][j]; 
	}
	for(int i=1;i<=m;i++)
		ave[i]=sum[i]*1.0/m;
	for(int j=1;j<=m;j++)
	{
		for(int i=1;i<=m;i++)
		{
			double t;
			t=abs(b[i][j]-ave[j]);
			if(t>15.0)
			{
				sum[j]=sum[j]-b[i][j];
				cnt[j]++;
			}
		}
	}
	for(int i=1;i<=m;i++)
		ave[i]=round(sum[i]*1.0/(m-cnt[i]));
	for(int i=1;i<=n;i++)
	{
		ans[i].x=round(a[i].x*0.6+ave[a[i].c-'A'+1]*0.4);
		ans[i].c=a[i].c;
	}	
	sort(ans+1,ans+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		cout<<round(ans[i].x)<<" "<<ans[i].c<<endl;
	}
	return 0;
}

B1024 程序员节发橙子

题目链接

解题思路:
1 、从后开始找每次找出前一个比后一个大的,然后如果大的话就将该处记为后一个+1,如果相等的话就记为后一个。
c数列存
2、从前开始找,找前一个比后一个大的话,则为前一个+1,
d数列存
然后答案既为c、d数列的最大值,因为这样就使得这个位置的数,前面的人可以分配好,后面的人也可以分配好。

坑点:sum注意开ll,会超出整型范围

代码:

#include
#define sc(x) scanf("%lld",&x);
#define pf printf
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define dep(i,e,s) for(int i=e;i>=s;i--)
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int a[maxn],b[maxn],c[maxn],d[maxn];
int main()
{
	SIS;
	//¼ÓËÙcin/cout
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	b[1]=a[1];
	for(int i=2;i<=n;i++)
	{
		b[i]=a[i]-a[i-1];
	}
	c[n]=1;
	for(int i=n-1;i>=1;i--)
	{
		c[i]=1;
		if(b[i+1]<0)
			c[i]=c[i+1]+1;
		if(b[i]==0)
			c[i]==c[i+1];
	}
	d[1]=1;
	for(int i=2;i<=n;i++)
	{
		d[i]=1;
		if(b[i]>0)
			d[i]=d[i-1]+1;
	}
	ll sum=0;
	for(int i=1;i<=n;i++)
		sum=sum+ll(max(c[i],d[i]));
	cout<<sum<<endl;
	return 0;
}

C众数出现的次数

题目链接

这道题应该是本场比赛最简单的一道题了吧。。。(个人理解)
题解:建立一个map,然后呢每次把a和a^b加进去,如果a==b时,a ^ b == a所以,这个时候就得剔除掉一个。然后找次数最大。并且记录次数最大的最小值,结束。

#include
#define sc(x) scanf("%lld",&x);
#define pf printf
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define dep(i,e,s) for(int i=e;i>=s;i--)
using namespace std;
typedef long long ll;
const int maxn=1e6+7;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int a[maxn],b[maxn],c[maxn];
int n;
map<int,int> mp1,mp2,mmp;
int main()
{
	SIS;
	//¼ÓËÙcin/cout
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i]>>b[i];
		b[i]=a[i]^b[i];
		//cout<
		mp1[a[i]]++;
		mp1[b[i]]++;
		if(a[i]==b[i])
			mp1[a[i]]--;
	}
	int ans=0;
	int s=0;
	for(map<int,int>::iterator it=mp1.begin();it!=mp1.end();it++)
	{
		//cout<first<<" "<second<<"tt "<
		if(it->second>s){
			ans=it->first;
			s=it->second;
		}
	}
	cout<<ans<<endl;
	return 0;
}

D特殊的翻转

题目链接
解题思路:
两种翻转策略:
将16进制转换为2进制,每次既转换为4个二进制数,比如16进制下的12既为2进制下的0001 0010;16进制下的AB既为2进制下的1010 1011,好了
转换后注意去除前导0.
**策略1:**开始翻第一个和第二个数。之后便翻转自己这个位置P[i] ,P[i+1],还有P[i+1],只当当前数为1时才需要翻转。翻转结束,后判断最后一个字母是否为0,如果是该策略可以。

策略2: 翻转P[i] ,P[i+1],P[i+2];也只翻转当前位置为1时,翻转结束,判断最后一个字母是否为0,如果是则该策略可以。

找出最优策略即可。

代码:

#include
#define sc(x) scanf("%lld",&x);
#define pf printf
#define rep(i,s,e) for(int i=s;i<=e;i++)
#define dep(i,e,s) for(int i=e;i>=s;i--)
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
string p[]={"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
char rev(char c)
{
	if(c=='1')
		return '0';
	else return '1';
}
int main()
{
	SIS;
	//¼ÓËÙcin/cout
	string s,ss="";
	cin>>s;
	for(int i=0;i<s.size();i++)
	{
		if(s[i]>='0' && s[i]<='9')
			ss=ss+p[s[i]-'0'];
		else
			ss=ss+p[s[i]-'A'+10];
	}
	int pos=0;
	for(int i=0;i<ss.size();i++)
	{
		if(ss[i]=='1')
		{
			pos=i;
			break;
		}
	}
	int num1=0,num2=0;
	string s1,s2;
	s1 = s2 = ss.substr(pos,ss.length()-pos);
	for(int i=1;i<s1.size();i++)
	{
		if(i==1)
		{
			num1++;
			s1[i-1]=rev(s1[i-1]);
			s1[i]=rev(s1[i]);
		}
		else
		{
			if(s1[i-1]=='1')
			{
				num1++;
				s1[i-1]=rev(s1[i-1]);
				s1[i]=rev(s1[i-1]);
				s1[i+1]=rev(s1[i+1]);
			}
		}
	}
	int flag1=1,flag2=1;
	if(s1[s1.size()-1]=='1') flag1=0;
	for(int i=1;i<s2.size();i++)
	{
		if(s2[i-1]=='1')
		{
			num2++;
			s2[i-1]=rev(s2[i-1]);
			s2[i]=rev(s2[i]);
			s2[i+1]=rev(s2[i+1]);
		}
	}
	if(s2[s2.size()-1]=='1') flag2=0;
	if(s1.size()==1 || s1.size()==0)
		cout<<s1.size()<<endl;
	else if(!flag1 && !flag2)
		cout<<"No"<<endl;
	else
	{
		if(!flag1) cout<<num2<<endl;
		else if(!flag2) cout<<num1<<endl;
		else cout<<min(num1,num2)<<endl;
	}
	return 0;
}

你可能感兴趣的:(洛谷 传智杯)