苏州大学ICPC集训队新生赛第二场

A - Score

 UVA - 1585

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    while(n--){
    int sum=0;
    string s;
    cin>>s;
    int len=s.size();
    int tmp=0;
    for(int i=0;i<len;i++){
    if(s[i]=='O')sum+=tmp,tmp++;
    else {
    sum+=tmp;
    tmp=0;
    }
    }
    sum+=tmp;
    cout<<sum<<endl;
    }   
    return 0;
}
View Code

B - Tetrahedron

 CodeForces - 166E 

题意:四面体,从D走n-1步回到D点,问你有多少种走法,数据量1e7;

标准错误解法:广搜:

#include<iostream>
#include<queue>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
#define pb push_back
#define pf push_front
#define fi first
#define se second 11
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef double db;
// const db PI=acos(-1.0);
const ll INF=0x3f3f3f3f3f3f3f3fLL;
const int inf=0x3f3f3f3f;//0x7fffffff;
const double eps=1e-9;
const ll MOD=1e9+7;
const int maxn=1e3+5;
ll n,ans;
struct node{int id;ll step;node(int x,ll y){id=x,step=y;}};
void bfs(){
    queue<node>Q;
    Q.push(node(4,0));
    while(!Q.empty()){
    node tmp=Q.front();
    Q.pop();
    if(tmp.step==n&&tmp.id==4){
    ans++;
    }
    if(tmp.id==1&&tmp.step<n){
    int t=(tmp.step+1)%MOD;
    Q.push(node(2,t));
    Q.push(node(3,t));
    Q.push(node(4,t));
    }
    if(tmp.id==2&&tmp.step<n){
        int t=(tmp.step+1)%MOD;
    Q.push(node(3,t));
    Q.push(node(4,t));
    Q.push(node(1,t));
    }
    if(tmp.id==3&&tmp.step<n){
    int t=(tmp.step+1)%MOD;
    Q.push(node(1,t));
    Q.push(node(2,t));
    Q.push(node(4,t));
    
    }
    
    if(tmp.id==4&&tmp.step<n){
    int t=(tmp.step+1)%MOD;
    Q.push(node(1,t));
    Q.push(node(2,t));
    Q.push(node(3,t));
    }
    }
}
int main(){
    cin>>n;
    ans=0;
    bfs();
    cout<<ans<<endl;
    // system("pause");
    return 0;
}
View Code

fyh正解:dp;

这个很像dp,定义状态:  dp(i,j)为走i步,到了 j 点 ;

每走一步都受前面状态影响:转移方程为:    dp[i][j]+=dp[i-1][k];   

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i=(int)j;i<=(int)k;i++)
#define per(i,j,k) for(int i=(int)k;i>=(int)j;i--)
#define pb push_back
#define pf push_front
#define fi first
#define se second 11
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef double db;
// const db PI=acos(-1.0);
const ll INF=0x3f3f3f3f3f3f3f3fLL;
const int inf=0x3f3f3f3f;//0x7fffffff;
const double eps=1e-9;
const ll MOD=1e9+7;
const int maxn=1e7+5;
int dp[maxn][4];
int main(){
   int n;
   cin>>n;
   dp[0][0]=0;
   dp[1][1]=1;
   dp[1][2]=1;
   dp[1][3]=1;
   for(int i=2;i<=n;i++)
   for(int j=0;j<=3;j++){
   for(int k=0;k<=3;k++){
   if(j==k)continue;
   dp[i][j]+=dp[i-1][k];       
   // else dp[i][j]=
   dp[i][j]%=MOD;
   }
   }
   cout<<dp[n][0]<<endl;
    return 0;
}
View Code

 

G - Jumping Jack

 CodeForces - 11B

题意:给你一个x   小于1e9;问你从0走到x要走几步;

解法:这题本来想广搜,问题和抓住那头牛很像,但数据量太大,搜索爆炸,本来想优化,但怎么搞呢?

正解:你想他 想左走向右走,在第n步,本来走  n+n+1,但现在变成了   -n+n+1,相差  2*n  步,这是个微调;

那你直接一直跳,超过的步数如果是偶数,就n/2步,是奇数肯定不能这样微调的,只能继续走。

和抓住这头牛 不一样,这题向左再向右是有策略的 ,可以微调的;

#include<bits/stdc++.h>
using namespace std;
int main(){
    int  x;
    cin>>x;
    if(x<0)x=-x;
    int sum=0;
    int i;
    for(i=0; ;i++){
    sum+=i;
    if(sum==x)break;
    else if(sum>x&&(sum-x)%2==0)break;
    
    }
    cout<<i<<endl;
    return 0;
}
View Code

D - Ehab and a 2-operation task

 CodeForces - 1088C

这题傻眼了:

题意:让你对一个序列进行n+1次操作。怎么把它变成严格单增的序列;

做法:先模1,这样全都清空为0,然后都变成2*n,一步步取余,最后就是单增得了;

但是为什么不是2n呢,手算一下就知道了,后面会重合;

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,k;
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&k);
    printf("%d\n",n+1);
    printf("2 %d 1\n",n);
    printf("1 %d %d\n",n,2*n);
    for(int i=1;i<n;i++){
    printf("2 %d %d\n",i,2*n-i);
    }
    
    return 0;
}
View Code

 

C - Permute Digits

 CodeForces - 915C 

题意:给你a,b,让你把a变成小于b的最大数。
解法:开始大模拟:
但一直wa,后来又mqf给了这样一组数据;3517 3503,
开始没有考虑取不到解的情况。
就是你一直取大于小于的,如果后面无解呢?只能回退,让前面的变小。
这点没考虑到。
然后模拟一直崩,有时间再来调一下。

错误解法:

#pragma comment(linker, "/STACK:102400000,102400000")
#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define pf push_front
#define fi first
#define se second 11
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef double db;
const db PI=acos(-1.0);
const ll INF=0x3f3f3f3f3f3f3f3fLL;
const int inf=0x3f3f3f3f;//0x7fffffff;
const double eps=1e-9;
const ll MOD=1e9+7;
const int maxn=1e7+5;
int vis[20];
bool flag;
int find(int x){
    for(int j=9;j>=0;j--){
    if(!flag&&vis[j]>0&&j<=x){
        if(j<x)flag=1;
        vis[j]--;
        return j;
        }

    else if(flag&&vis[j]>0){
        vis[j]--;
        return j;  
        
    }
    }
    return -1;
}
int main(){    

    flag=0;
    string sa,sb;
    cin>>sa>>sb;
    if(sa.size()<sb.size()){
    sort(sa.begin(),sa.end());
    int len=sa.size();
    for(int i=len-1;i>=0;i--)//逆序输出
    cout<<sa[i];
    }

    else {
    memset(vis,0,sizeof vis);
    // vector<int>ans;
    int ans[20];
    int len=sa.size();
    for(int i=0;i<len;i++){
    int tmp=sa[i]-'0';
    vis[tmp]++;
    }
    
    len=sb.size();
    int i;
    for( i=0;i<len;i++){
    int t=sb[i]-'0';
    int tmp=find(t);
    if(tmp!=-1)ans[i]=tmp;
    else {

    while(tmp==-1){
    i--;
    vis[ans[i]]++;
    t=sb[i]-'0'-1;
    tmp=find(t);
    }
    ans[i]=tmp;
    vis[tmp]--;
    flag=1;
    }
    
    }
    // int p=0;
    // while(ans[p]==0&&p!=len-1)p++; 

    for(int i=0;i<len;i++)
    cout<<ans[i];
    }
    return 0;
}
// 1753
View Code

正确解法:用string里的大小比较,默认最小,然后每次从最高位开始找,能替换就替换掉。
如果替换后大于b,就退回来,确实很巧妙。

#include<bits/stdc++.h>
using namespace std;
int main(){
    string t,a,b;
    cin>>a>>b;
    sort(a.begin(),a.end());
    if(a.size()<b.size()){
    reverse(a.begin(),a.end());
    }
    else {
    int len=a.size();
    int L,R;
    for(L=0;L<len;L++){
    R=len-1;
    t=a;
    while(L<R){
    swap(a[L],a[R--]);
    sort(a.begin()+L+1,a.end());
    if(a>b)a=t;
    else break;
    }
    
    }
    
    }
    cout<<a<<endl;
    return 0;
}
View Code

E - System Administrator

英语吓得不轻;

#include<bits/stdc++.h>
using namespace std;
int main(){
    int suma=0,sumb=0,oka=0,okb=0;
    int n,t,x,y;
    cin>>n;
    while(n--){
    cin>>t>>x>>y;
    if(t==1){
    suma+=10;
    oka+=x;
    }
    else {
    sumb+=10;
    okb+=x;
    }
    }
    if(oka>=suma/2)cout<<"LIVE"<<endl;
    else cout<<"DEAD"<<endl;
    if(okb>=sumb/2)cout<<"LIVE"<<endl;
    else cout<<"DEAD"<<endl;

    return 0;
}
View Code

 

F - Squares

 CodeForces - 263B 

看清题意就好了,站在边上的不算属于这个空间;

#include<bits/stdc++.h>
using namespace std;
int a[100];
int main(){
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    if(k>n)cout<<"-1"<<endl;
    else {
    cout<<a[n-k+1]<<" "<<a[n-k+1]<<endl;
    }
    return 0;
}
View Code

 

 

posted @ 2020-02-27 23:47  无声-黑白  阅读(159)  评论(0编辑  收藏  举报