传智杯:
没ak。。。
题目链接
题意:看题易知
解题思路:
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;
}
题目链接
解题思路:
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;
}
题目链接
这道题应该是本场比赛最简单的一道题了吧。。。(个人理解)
题解:建立一个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;
}
题目链接
解题思路:
两种翻转策略:
将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;
}