听队友说今天发博客有个1024奖章?草稿箱的发一篇出来
Contest:http://codeforces.com/contest/1151
像我这样的辣鸡只能看着大佬过题QAQ。
A. Maxim and Biology(暴力)
题目链接:http://codeforces.com/contest/1151/problem/A
题目大意:给出一个n长度的字符串,消去一些字符,并且变换一些字符,使得最后的字符串变为ACTG。问最小的变换次数。
思路:由于n长度只有50,遍历即可。
ACCode:
string s;
int n;
int main(){
std::ios::sync_with_stdio(false);
string a="ACTG";
while(cin>>n){
cin>>s;
int len=n,ans=INF32;
for(int i=0;i<=n-4;++i){
int res=0;
for(int j=0;j<4;++j){
if(s[i+j]<a[j]){// A Z
res+=min(a[j]-s[i+j],s[i+j]+26-a[j]);
// cout<<a[j]-s[i+j]<<" , "<<s[i+j]-a[j]+26<<endl;
}
else{//Z A s[i+j]>=a[j]
res+=min(s[i+j]-a[j],a[j]+26-s[i+j]);
// cout<<s[i+j]-a[j]<<" , "<<a[j]-s[i+j]+26<<endl;
}//cout<<res<<endl;
}//cout<<"res: "<<res<<endl;
ans=min(ans,res);
}cout<<ans<<endl;
}
}
B. Dima and a Bad XOR(思维
题目链接:http://codeforces.com/contest/1151/problem/B
题目大意:给出一个n*m的矩阵,每行取一个数进行异或和,判断最后得到的数是否能 不为0。可以输出TAK,并输出选择的那些n行,i列。否则输出NTE。
思路:首先对一列进行异或和。然后遍历所有的其他的数,判断是否能够得到不为0的答案。存在则输出,否则遍历到最后输出NIE,至于为什么,不知道。
ACCode:
// luogu-judger-enable-o2
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
#define Pair pair<int,int>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
// register
const int MAXN=5e2+10;
const int INF32=0x3f3f3f3f;
const LL INF64=0x3f3f3f3f3f3f3f3f;
const int MOD=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);
int DP[MAXN][MAXN];
int a[MAXN][MAXN];
int n,m;
int main(){
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
scanf("%d",&a[i][j]);
}
}
int ans=0;
for(int i=1;i<=n;++i){
ans^=a[i][1];
}
if(ans){
printf("TAK\n");
for(int i=1;i<=n;++i) printf("1\n");
continue;
}int flag=0;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
int res=ans^a[i][j]^a[i][1];
if(res){
flag=1;
printf("TAK\n");
for(int k=1;k<i;++k) printf("1\n");
printf("%d\n",j);
for(int k=i+1;k<=n;++k) printf("1\n");
break;
}
}
if(flag) break;
}
if(flag==0) printf("NIE\n");
}
}
C. Problem for Nazar(数学
题目大意:两个数组,分别是奇数数组(1,3,5,7,...)偶数数组(2,4,6,...).然后组成一个新的数组c(1,2,4,3,5,7,6,8,10....)就是每个都是以2^n个对应的数组。对于l,r求出sum(c[l]~c[r])。
思路:获得[l,r]区间奇数和偶数的个数,然后用等差数列加一下就好了,注意可能会爆ll,因此最后要MOD和用逆元进行/2操作。
ACCode:
// luogu-judger-enable-o2
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define Pair pair<ll,ll>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// ??
//std::ios::sync_with_stdio(false);
// register
const int MAXN=5e2+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const int MOD=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);
Pair Solve(ll res){
ll odd=0,even=0;
for(int i=0;res>=(1<<i);++i){
// cout<<res<<" "<<i<<endl;
if(i&1){//奇数,偶区间
even+=(1ll<<i);
res-=(1ll<<i);
if(res<=(1ll<<i+1)){
odd+=res;break;
}
}
else{//偶数,奇区间
odd+=(1ll<<i);
res-=(1ll<<i);
if(res<=(1ll<<i+1)){
even+=res;break;
}
}
}//cout<<odd<<" "<<even<<endl;
return make_pair(odd%MOD,even%MOD);
}
ll PowMod(ll a,ll b){
ll ret=1;
while(b){
if(b&1) ret=(ret*a)%MOD;
a=(a*a)%MOD;
b=b>>1;
}return ret;
}
int main(){
ll l,r;scanf("%lld%lld",&l,&r);
Pair front=Solve(l-1),last=Solve(r);
ll res=PowMod(2,MOD-2);
// cout<<last.first<<" "<<last.second<<endl;
ll ans=((1+1+(last.first-1)*2)%MOD *last.first%MOD *res%MOD)%MOD;
// cout<<ans<<" ";
ans=(ans+(2+2+(last.second-1)*2)%MOD *last.second%MOD *res%MOD)%MOD;
// cout<<ans<<" ";
ans=(ans+MOD-(1+1+(front.first-1)*2)%MOD *front.first%MOD *res%MOD)%MOD;
// cout<<ans<<" ";
ans=(ans+MOD-(2+2+(front.second-1)*2)%MOD *front.second%MOD *res%MOD)%MOD;
printf("%lld\n",ans%MOD);
}
D. Stas and the Queue at the Buffet(思维,贪心
题目链接:http://codeforces.com/contest/1151/problem/D
题目大意:n个人站成一排,每个人有两个属性,l,r,每个人的伤心值是(左边人数*l+右边人数*r),输出最小的每个人的伤心值之和。
思路:按照l-r进行排序,小的在左边,表示左边占有的比重较高。
ACCode:
const int MAXN=1e5+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const int MOD=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);
Pair arr[MAXN];
int n;
int Cmp(Pair a,Pair b){
return a.first-a.second>b.first-b.second;
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;++i){
scanf("%d%d",&arr[i].first,&arr[i].second);
}sort(arr+1,arr+1+n,Cmp);
ll res=0;
for(int i=1;i<=n;++i){
res+=1ll*(i-1)*arr[i].first+1ll*(n-i)*arr[i].second;
}printf("%lld\n",res);
}
}