题目意思:
有n(n为偶数)个x和X,求最少的变换次数,使得X的个数为n/2,输出变换后的序列。
解题思路:
统计X的个数ans,和n/2比較,少了的话,须要把n/2-ans个x变成X,多了的话须要把ans-n/2个X变成x.(从前往后扫一遍即可了)。
代码:
//#include<CSpreadSheet.h> #include<iostream> #include<cmath> #include<cstdio> #include<sstream> #include<cstdlib> #include<string> #include<string.h> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #include<bitset> #include<cmath> #define eps 1e-6 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll __int64 #define LL long long #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #define M 1000000007 //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; char save[220]; int n; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d",&n)) { int ans=0; scanf("%s",save+1); for(int i=1;i<=n;i++) if(save[i]=='X') ans++; printf("%d ",abs(n/2-ans)); if(ans<n/2) { int cnt=0; for(int i=1;i<=n;i++) { if(cnt>=(n/2-ans)) { printf("%c",save[i]); continue; } if(save[i]=='x') { cnt++; printf("X"); } else printf("X"); } } else { int cnt=0; for(int i=1;i<=n;i++) { if(cnt==(ans-n/2)) { printf("%c",save[i]); continue; } if(save[i]=='X') { cnt++; printf("x"); } else printf("x"); } } putchar(' '); } return 0; }
CF 424B. Megacity
题目意思:
给一个中心城市的坐标(0,0)和人口s,n个周围城市。告诉n个城市的人口及位置坐标,求以中心城市为圆心的最小的半径,使得人口总数超过1000000-s.
解题思路:
先求出每一个城市距离中心城市的距离,然后对距离从小到大排序,然后依次扫描,假设达到要求,就退出输出最小的半径。
代码:
//#include<CSpreadSheet.h> #include<iostream> #include<cmath> #include<cstdio> #include<sstream> #include<cstdlib> #include<string> #include<string.h> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #include<bitset> #include<cmath> #define eps 1e-6 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll __int64 #define LL long long #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #define M 1000000007 //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define Maxn 1100 struct Point { double x,y; double dis; int v; }pp[Maxn]; int n,s; int dp[Maxn]; bool cmp(struct Point a,struct Point b) { return a.dis<b.dis; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&s)) { for(int i=1;i<=n;i++) { double x,y; scanf("%lf%lf%d",&x,&y,&pp[i].v); pp[i].x=x; pp[i].y=y; pp[i].dis=sqrt(x*x+y*y); } sort(pp+1,pp+n+1,cmp); /*for(int i=1;i<=n;i++) printf("i:%d %lf ",i,pp[i].dis);*/ double ans; if(s>=1000000) { printf("0 "); continue; } int lef=1000000-s; int i=1; while(lef>0&&i<=n) { ans=pp[i].dis; lef-=pp[i].v; i++; } if(lef>0) { printf("-1 "); continue; } printf("%lf ",ans); } return 0; }
题目意思:
给定pi,求Q。
解题思路:
抑或运算满足交换律和结合律。
原式能够等价于先对pi所有抑或。然后对每一个i(1=<i<=n),求出1~n对i求模再抑或,能够发现一直是1~i-1 1~i-1..... 所以假设n/i是偶数抑或值为0。假设是奇数抑或值为1^2^3^4...^i-1 最后余数是1~n%i .
预处理出dp[i]=1^2^3..^i
代码:
//#include<CSpreadSheet.h> #include<iostream> #include<cmath> #include<cstdio> #include<sstream> #include<cstdlib> #include<string> #include<string.h> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #include<bitset> #include<cmath> #define eps 1e-6 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll __int64 #define LL long long #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #define M 1000000007 //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define Maxn 1100000 int dp[Maxn]; int n; void init() { dp[0]=0; for(int i=1;i<=1000000;i++) dp[i]=dp[i-1]^i; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); init(); while(~scanf("%d",&n)) { int ans=0; for(int i=1;i<=n;i++) { int p; scanf("%d",&p); ans=ans^p; if((n/i)&1) //ÆæÊý { ans=ans^dp[i-1]; } ans=ans^dp[n%i]; } printf("%d ",ans); } return 0; }
CF 424D. Biathlon Track
题目意思:
给一个2维矩阵。给三个參数tp(相等),tu(大于),td(小于),t(总时间),每一个格子有个权值,求一个矩阵(长>=3&&宽>=3),使得边缘走完的总时间T,与t尽可能靠近。输出矩阵的左上角坐标和右下角坐标。
解题思路:
dp+预处理
o(n^3*lgn) 枚举两列i,j 把最后一行的 形如 |_| 值丢进set里,从第n-2行開始枚举,求出形如 |_| 的值v,二分查找t-v 找到最接近的,更新。
使用set<pair<int,int> >里的lower_bound函数。
此题的关键在于仅仅用枚举三维。两列和一行 构造 |_| 形状。直接用lower_bound得出最接近的矩形的值。
l[i][j]表示从位置(i,j)水平走到左边界的时间值
r[i][j]表示从最左边向右水平走到位置(i,j)所需时间值
u[i][j]表示从位置(i,j)竖直向上走到上边界的时间值
d[i][j]表示从上边界竖直向下走到位置(i,j)所需时间值
代码:
//#include<CSpreadSheet.h> #include<iostream> #include<cmath> #include<cstdio> #include<sstream> #include<cstdlib> #include<string> #include<string.h> #include<cstring> #include<algorithm> #include<vector> #include<map> #include<set> #include<stack> #include<list> #include<queue> #include<ctime> #include<bitset> #include<cmath> #define eps 1e-6 #define INF 0x3f3f3f3f #define PI acos(-1.0) #define ll __int64 #define LL long long #define lson l,m,(rt<<1) #define rson m+1,r,(rt<<1)|1 #define M 1000000007 //#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define Maxn 330 int save[Maxn][Maxn],l[Maxn][Maxn],r[Maxn][Maxn],u[Maxn][Maxn],d[Maxn][Maxn]; int n,m,t; set<pair<int,int> >mys; int x1,yy1,x2,y2; int tp,tu,td,ans; void get() { for(int i=0;i<=n;i++) save[i][0]=0; for(int i=0;i<=m;i++) save[0][i]=0; //memset(l,0,sizeof(l)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(j!=1) //这个能够不要 仅仅求时间差 { if(save[i][j]>save[i][j-1]) r[i][j]=r[i][j-1]+tu,l[i][j]=l[i][j-1]+td; else if(save[i][j]==save[i][j-1]) r[i][j]=r[i][j-1]+tp,l[i][j]=l[i][j-1]+tp; else r[i][j]=r[i][j-1]+td,l[i][j]=l[i][j-1]+tu; } if(i!=1) //这个能够不要 仅仅求时间差 { if(save[i][j]>save[i-1][j]) u[i][j]=u[i-1][j]+td,d[i][j]=d[i-1][j]+tu; else if(save[i][j]==save[i-1][j]) u[i][j]=u[i-1][j]+tp,d[i][j]=d[i-1][j]+tp; else u[i][j]=u[i-1][j]+tu,d[i][j]=d[i-1][j]+td; } //printf("i:%d j:%d r:%d l:%d u:%d d:%d ",i,j,r[i][j],l[i][j],u[i][j],d[i][j]); //system("pause"); } } int get_down(int i,int j,int k) //求出 |_| { return d[k][j]+u[k][i]+l[k][j]-l[k][i]; } int get_up(int i,int j,int k) //求出 |_| 注意两竖的为负。方向 { return -d[k][j]-u[k][i]+r[k][j]-r[k][i]; } void update(int i,int j,int k,set<pair<int,int> >::iterator it,int up) { int ff=(*it).first,ss=(*it).second; if(abs(ff+up-t)<ans) { ans=abs(ff+up-t); x1=k,yy1=i; x2=ss,y2=j; } } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d%d",&n,&m,&t)) { scanf("%d%d%d",&tp,&tu,&td); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&save[i][j]); get(); ans=INF; for(int i=1;i<=m;i++) { for(int j=i+2;j<=m;j++) { mys.clear(); mys.insert(make_pair(get_down(i,j,n),n)); for(int k=n-2;k>=1;k--) { int temp=get_up(i,j,k); set<pair<int,int> >::iterator it; it=mys.lower_bound(make_pair(t-temp,k)); if(it!=mys.end()) update(i,j,k,it,temp); if(it==mys.begin()) { mys.insert(make_pair(get_down(i,j,k+1),k+1)); continue; } it--; update(i,j,k,it,temp); mys.insert(make_pair(get_down(i,j,k+1),k+1)); } } } //printf("%d ",get_up(1,4,1)+get_down(1,4,4)); //printf("%d ",ans); printf("%d %d %d %d ",x1,yy1,x2,y2); } return 0; }