2018 NOIP集训(三)

A题 Tree

问题描述

给定一颗 n 个点的树,树边带权,试求一个排列 P ,使下式的值最大
\sum_{i=1}^{n-1} maxflow(P_i, P_{i+1})
其中 maxflow(s, t) 表示从点 s 到点 t 之间的最大流,即从 st 的路径上最小的边权

输入格式

第一行一个整数 n ,表示点数

下接 n - 1 行,每行三个数 u, v,w 表示一条连接点 u 和点 v 权值为 w 的边

输出格式

输出一行一个整数,表示答案

数据范围

对于前 5\% 的数据满足 n \leq 8

对于前 40\% 的数据满足 n \leq 200

对于前 60\% 的数据满足 n \leq 2000

对于 100\% 的数据满足 n \leq 100000

样例

样例输入
2
1 2 2333
样例输出
2333

题解

事实上是一道十行代码就可以解决的题目
如果要让\sum_{i=1}^{n-1}maxflow(P_i, P_{i+1})的边权值最小,就要让每一条边只被经过一次,那么将所有边的权值相加就好了QAQ(网上的题解都是些什么玩意。。。)

#include<bits/stdc++.h>
using namespace std;
long long n,ans,u,v,w;
int main(){
    cin>>n;
    for(register long long i=1;i<n;i++)cin>>u>>v>>w,ans+=w;
    cout<<ans<<endl;
    return 0;
}


B题 Permutation

问题描述

给定一张 n 个点 m 条边的无向图,每条边连接两个顶点,保证无重边自环,不保证连通

你想在这张图上进行若干次旅游,每次旅游可以任选一个点 x 作为起点,再走到一个与 x
接有边相连的点 y ,再走到一个与 y 直接有边相连的点 z 并结束本次旅游

作为一个旅游爱好者,你不希望经过任意一条边超过一次,注意一条边不能即正向走一次又反
向走一次,注意点可以经过多次,在满足此条件下,你希望进行尽可能多次的旅游,请计算出最多
能进行的旅游次数并输出任意一种方案

输入格式

1 行两个正整数 nm ,表示全图的点数与边数
下接 m 行,每行两个数字 uv 表示一条边

输出格式

1 行一个整数 cnt 表示答案

下接 cnt 行,每行三个数字 x , yz ,表示一次旅游的路线

如有多种旅行方案,任意输出一种即可

数据范围

对于前 20\% 的数据, n < 10,m \leq 20 .

对于令 20\% 的数据, m = n - 1 ,并且图连通

对于令 10\% 的数据,每个点的度数不超过 2

对于 100\% 的数据, n \leq 100000,m \leq 200000

样例

样例输入
4 5
1 2
3 2
2 4
3 4
4 1
样例输出
2
4 1 2
4 3 2

题解

部分分方法很容易想到,DFS或者BFS直接遍历查找即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010,maxm = 200010;
/*
struct edge{
    int v,next;
    bool used;
}E[maxm*2];
*/
struct anss{
    int a,b,c;
};
vector<int> G[maxn];
//priority_queue< pair<int,int> , vector<pair<int,int>>, less<pair<int,int>> > pq;
int p[maxn],eid;
int degree[maxn];
/*
void init(){
    memset(p,-1,sizeof p);
    eid = 0;
}
*/
inline void insert(int u,int v){
    G[u].push_back(v);
}
inline void insert2(int u,int v){
    insert(u,v);
    insert(v,u);
}
int n,m;
inline bool cmp(const int &a,const int &b){
    if(degree[a] == degree[b]){
        return a < b;
    }else{
        return degree[a] < degree[b];
    }
}
int main(){
    scanf("%d%d",&n,&m);
    memset(degree,0,sizeof degree);
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        insert2(u,v);
        degree[u]++;
        degree[v]++;
    }
    for(int i=1;i<=n;i++){
        sort(G[i].begin(),G[i].end(),cmp);
    }
    int cnt = 0;
    //int tcnt[maxn] = {0};
    vector<anss> ansss;
    for(int i=1;i<=n;i++){
        while(degree[i] >= 2){
            //cout << "i:" << i << " degree: " << degree[i] << endl;
            //ansss.push_back({G[i][tcnt[i]*2-2],i,G[i][tcnt[i]*2-1]});
            int son1 = -1,son2 = -1;
            int savep;
            int pp = 0;
            sort(G[i].begin(),G[i].end(),cmp);
            //cout << "savep:" << savep << endl;
            son1 = G[i][0],son2 = G[i][1];
            //cout << "son1:" << son1 << "son2:" << son2 << endl;
            for(int ppp=0;ppp<G[son1].size();ppp++){
                if(G[son1][ppp] == i){
                    //cout << "ppp1:" << ppp << endl;
                    G[son1].erase(G[son1].begin() + ppp);
                    break;
                }
            }
            
            for(int ppp=0;ppp<G[son2].size();ppp++){
                if(G[son2][ppp] == i){
                    //cout << "ppp1:" << ppp << endl;
                    G[son2].erase(G[son2].begin()+ppp);
                    break;
                }
            }
            G[i].erase(G[i].begin()+1);
            G[i].erase(G[i].begin());
            ansss.push_back({son1,i,son2});
            degree[i] -= 2;
            degree[son1]--;
            degree[son2]--;
            cnt++;
        }
    }
    printf("%d\n",cnt);
    for(int i=0;i<ansss.size();i++){
        printf("%d %d %d\n",ansss[i].a,ansss[i].b,ansss[i].c);
    }
    return 0;
}

这种方法的错误性也很容易发现。任意一个强连通图都有可能导致错误,即使是部分强联通也会出导致错误。所以我们需要找其他的思路。
首先我们可以发现,答案输出的第一行总是所有联通块中的边集\Sigma{m/2},此时我们在每个联通块中任选一点做生成树,并从根节点向下遍历,每找到两条相连边就记录一次即可。当然遍历的顺序也很讲究,要先查叶子节点的所连的边再查父亲节点的所连的边,这样才能玄学保证最优

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=4e5+10;
inline char get(){
    static char buf[30],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    register char c=get();register int f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
ll n,m,num[maxn],fa[maxn];
bool vis[maxn];
struct edge{
    ll v;
    ll next;
}e[maxn];
ll p[maxn],t=0;
ll edge[maxn];
struct Path{
    ll a,b,c;
};
vector<Path> ans;
void insert(ll u,ll v){
    e[t].v=v;
    e[t].next=p[u];
    p[u]=t++;
}
void insert2(ll u,ll v){
    insert(u,v);
    insert(v,u);
}
void BFS(ll rt){
    ll x,H=0,T=1;
    num[T]=rt;
    fa[rt]=-1;
    while(H-T){
        ll u=num[++H];
        for(ll i=p[u];i!=-1;i=e[i].next){
            ll v=e[i].v;
            if(!fa[v]){
                fa[v]=u;
                num[++T]=v;
            }
        }
    }
    for(x=T;x>=1;x--){
        ll u=num[x];
        edge[0]=0;
        for(ll i=p[u];i!=-1;i=e[i].next){
            ll v=e[i].v;
            if(!vis[i] && v!=fa[u])
                edge[++edge[0]]=i;
        }
        for(ll i=p[u];i!=-1;i=e[i].next){
            ll v=e[i].v;
            if(!vis[i] && v==fa[u])
                edge[++edge[0]]=i;
        }
        for(ll i=1;i+1<=edge[0];i+=2){
            vis[edge[i]]=vis[edge[i]^1]=true;
            vis[edge[i+1]]=vis[edge[i+1]^1]=true;
            ans.push_back((Path){e[edge[i]].v,u,e[edge[i+1]].v});
        }
    }
}
int main(){
    freopen("T1.txt","r",stdin);
    memset(p,-1,sizeof(p));
    n=read(),m=read();
    for(ll i=1;i<=m;i++){
        insert2(read(),read());
    }
    for(ll i=1;i<=n;i++)
        if(!fa[i])BFS(i);
    printf("%lld\n",(ll)ans.size());
    for(ll i=0;i<ans.size();i++)printf("%lld %lld %lld\n",ans[i].a,ans[i].b,ans[i].c);
    return 0;
}

C题 Permutation

问题描述

你有一个长度为 n 的排列 P 与一个正整数 K

你可以进行如下操作若干次使得排列的字典序尽量小

对于两个满足 \left|i-j\right| \geq K\left|P_i-P_j\right| =1的下标 ij ,交换 P_iP_j

输入格式

第一行包括两个正整数 nK

第二行包括 n 个正整数,第 i 个正整数表示 P_i

输出格式

输出一个新排列表示答案

输出共 n 行,第 i 行表示 P_i

数据范围

对于前 20\% 的数据满足 n \leq 6

对于前 50\% 的数据满足 n \leq 2000

对于 100\% 的数据满足 n \leq 500000

样例

样例输入
8 3
4 5 7 8 3 1 2 6
样例输出
1
2
6
7
5
3
4
8

题解

非常好的暴力训练题。考试的时候明显是在比谁骗的分多Orz
首先是大家都懂的20分普通暴力

#include <bits/stdc++.h>
#define maxn 500010
using namespace std;
inline char get(){
    static char buf[30],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    register char c=get();register int f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
struct edge{
    int u,v,w,next;
}E[maxn<<1],A[maxn<<1];
int p[maxn],eid=0;
void init(){
    for(register int i=0;i<maxn;i++)p[i]=-1;
    eid=0;
}
void insert(int u,int v,int w){
    E[eid].u=u;
    E[eid].v=v;
    E[eid].w=w;
    E[eid].next=p[u];
    p[u]=eid++;
}
void insert2(int u,int v,int w){
    insert(u,v,w);
    insert(v,u,w);
}
int n,k;
int t[maxn],a[maxn];
int main(){
    //freopen("T2.txt","r",stdin);
    n=read();k=read();
    for(register int i=1;i<=n;i++)a[i]=read();
    int flag=n;
    while(flag--) {
        for(register int i=1;i<=n;i++){
            for(register int j=i+k;j<=n;j++) {
                if(fabs(a[i]-a[j])==1 && a[i]>a[j]) {
                    int p=a[i];
                    int q=a[j];
                    a[i]=q;
                    a[j]=p;
                }
            }
        }
    }
    for (int i=1;i<=n;i++)cout<<a[i]<<endl;
    return 0;
}

道理都懂,直接暴力查找就好了(:з」∠)
然后是知识分子的剪枝暴力,用的时间要稍微少一点,去掉了对于无法转换的字符的判断,虽然复杂度的上限依然很大,但是下限减小了不少↓

//40分
#include <bits/stdc++.h>
using namespace std;
long long n,k,p[500010],t[500010];
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>p[i];
        t[i] = p[i];
    }
    sort(t+1,t+1+n);
    bool flag = 1; 
    int ts =1;
    while(flag){
        flag = 0;
        for(int i=ts;i<n;i++){
            int  tk = 0;
            for(int j=i+1;j<=n;j++){
                if(abs(p[i] - p[j]) == 1){
                    tk++;
                }
                if(abs(i - j) >= k && abs(p[i]-p[j])==1 && p[i]>p[j]){
                    long long temp = p[i];
                    p[i] = p[j];
                    p[j] = temp;
                    flag = 1;
                    /*for(int k=1;k<=n;k++){    
                        cout<<p[k]<<" ";
                    }
                    cout<<endl;*/
                }
                if(tk == 2){
                    break;
                }
            }
        }
        if(p[ts] == t[ts]){
            ts++;
            //cout<<p[ts]<<endl;
        }
    //  t++;
        //cout<<t<<endl;
    }
    for(int i=1;i<=n;i++){
        cout<<p[i]<<endl;
    }
    return 0;
}

PS:我也不知道为什么会变成40分QAQ
最后是大佬的玄学暴力。每一次遍历的时候提前处理判断当前是否是最佳答案,对于每一对ij而言,若ij的前面,那么每一次判断性质时只判断i-j是否等于1而不是abs(i-j),因为如果i-j=1成立就说明处在前方的数的值一定比处在后方的数的值要大,那么一定要执行交换操作。同理,如果j-i=1就说明交换之后整个串的字典序要大于交换之前,因此不做交换。

#include <bits/stdc++.h>
#define maxn 500005
using namespace std;
//tql
inline char get(){
    static char buf[30],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    register char c=get();register int f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
int n,m;
int a[maxn];
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;i++)a[i]=read();
    bool swaped;
    for(register int k=1;k<=n && swaped;k++){
        swaped=false;
        for(register int i=1;i<=n-m;i++){
            for(register int j=i+m;j<=n;j++){
                if(a[i]-a[j]==1){
                    swap(a[i],a[j]);
                    swaped=true;
                }
            }
        }
    }
    for(int i=1;i<=n;i++)printf("%d\n",a[i]);
    return 0;
}

讲完暴力我们再来看下正解。(转,正解让本弱鸡根本无法理解,会在正解后给出自己的解法)
作者:a6219221
来源:CSDN
原文:https://blog.csdn.net/a6219221/article/details/52456053

  1. 从input的内容来分:有2种,分别是有duplicate和no duplicate的

解法:这两种情况的结果其实有有同一个特性:在同一个position,同一种字母只能出现一次。只不过没有duplicate的情况下不需要额外处理就可以达到这个效果。针对有duplicate的情况,我们在每次的recursion中都需要设置一个set来储存这个位置已经使用过的数字或者字母。见如下的tree:

example: input is: 1, 1, 2
on each recursion level, we skip the duplicate number
                /       |      \
               1       [1]重复  2               n
             /  \     / \      |  \
            1    2   1   2     1  [1]重复       n * (n - 1)
           /    /   /   /      |   |
          2    1   2   1       1   1            n * (n - 1) * (n - 2)
 
time: O(n!)
space: O(n)
1 1 2
1 2 1
2 1 1
  1. 从input的type来分:

  2. 可以是array

  3. 可以是list

  4. 也可以是个string

区别:这里的区别在于是否能够in place操作其中的element。比如array就可以快速的swap里面的element,这时候我们的permutation就可以使用swap的方式。但是string是没有办法这样操作的。所以如果后面2种情况出现又想要做in place的话,最好是重新建立一个array来储存其中的内容。这样也可以避免List的get()的时间复杂度不恒定的问题。string可以使用toCharArray()来得到char的array

  1. 从output的要求来分:

1是不用output,就print出来。

2是要返回一个List<string>。

3是要返回一个List<List<Integer>>

区别: 1.如果不用output,我们可以写一个函数把那个array或者temp arraylist中的内容打印出来。这个问题一般不大

  1. 如果需要返回一个string,那么input一般来说是一个string或者是char array.这类的做法也比较方便,用swap的方法最后rst.add(new String(input))就可以实现

  2. 需要注意的是如果要求返回的值是List<List<Integer>>,那么最后加入rst的那步一定是需要一个一个把array中的数字添加到最后的list中去的。最好是这样做,可以保证不会出问题。因为并不是很麻烦而且不会出现想用现成函数用错的情况。毕竟list中的是object而array中的可能是permitIve type

贴上代码
#include<bits/stdc++.h>
using namespace std;

const int maxn=5e5+10;

void read(int &x)
{
    char c=getchar(); x=0;
    while (c<'0'||c>'9') c=getchar();
    while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
}

int n,k,p[maxn],q[maxn],deg[maxn];
int tote,FIR[maxn],TO[maxn<<1],NEXT[maxn<<1];
priority_queue<int> pq;

namespace SegTree{
    int mn[maxn<<2];
#define lc (nd<<1)
#define rc (nd<<1|1)
#define mid ((s+t)>>1)

    void init()
    {
        memset(mn,0x3f3f3f3f,sizeof(mn));
    }

    void update(int nd,int s,int t,int id,int val)
    {
        if (s==t) {mn[nd]=val; return;}
        if (id<=mid) update(lc,s,mid,id,val);
        else update(rc,mid+1,t,id,val);
        mn[nd]=min(mn[lc],mn[rc]);
    }

    int query(int nd,int s,int t,int l,int r)
    {
        if (l<=s&&t<=r) return mn[nd];
        int Ans=0x7fffffff;
        if (l<=mid) Ans=min(Ans,query(lc,s,mid,l,r));
        if (r> mid) Ans=min(Ans,query(rc,mid+1,t,l,r));
        return Ans;
    }
}

void addedge(int u,int v)
{
    TO[++tote]=v;
    NEXT[tote]=FIR[u];
    FIR[u]=tote;
    deg[v]++;
}

int main()
{
    int i,x;
    read(n); read(k);
    for (i=1;i<=n;i++)
        read(p[i]),q[p[i]]=i;
    SegTree::init();
    for (i=n;i>=1;i--)
    {
        x=SegTree::query(1,1,n,q[i]-k+1,q[i]);
        if (x<=n) addedge(q[x],q[i]);
        x=SegTree::query(1,1,n,q[i],q[i]+k-1);
        if (x<=n) addedge(q[x],q[i]);
        SegTree::update(1,1,n,q[i],i);
    }
    for (i=1;i<=n;i++)
        if (!deg[i]) pq.push(i);
    for (i=n;i>=1;i--)
    {
        int u=p[i]=pq.top(); pq.pop();
        for (int p=FIR[u];p;p=NEXT[p])
            if (!(--deg[TO[p]])) pq.push(TO[p]);
    }
    for (i=1;i<=n;i++) q[p[i]]=i;
    for (i=1;i<=n;i++) printf("%d\n",q[i]);
}
//转自一个ACM银牌选手

然后是本弱鸡的粉墨登场

首先我们要明确这是一个换位问题。这时我们假设有三个数a,b,c,如果ab可以交换位置且bc可以换位置,那么我们就可以知道a一定可以和c换位置。因此我们需要一个值来存储可以换位置的点。用什么方法可以很容易的判断两个元素处于同一个集合里呢?很显然是并查集。我们初始化每次判断i和j位置的值,如果ij可以换位置,就在并查集中合并ij,最后按字典序排列即可
这时我们就得到了一个看似正确的思路。事实上,这只正确了一半。因为当我们交换两个元素的位置后,他可以通往的位置会发生改变。因此这时我们需要再重复几次之前的步骤,直到最后所有元素都没法再交换位置得到最优解时再停止

#include<bits/stdc++.h>
#define maxn 500000
using namespace std;
inline char get(){
    static char buf[30],*p1=buf,*p2=buf;
    return p1==p2 && (p2=(p1=buf)+fread(buf,1,30,stdin),p1==p2)?EOF:*p1++;
}
inline int read(){
    register char c=get();register int f=1,_=0;
    while(c>'9' || c<'0')f=(c=='-')?-1:1,c=get();
    while(c<='9' && c>='0')_=(_<<3)+(_<<1)+(c^48),c=get();
    return _*f;
}
int fa[maxn];
int n,k;
void init(){
    for(register int i=0;i<=n;i++)fa[i]=i;
}
int get(int x){
    if(fa[x]==x)return x;
    return fa[x]=get(fa[x]);
}
int merge(int x,int y){
    x=get(x);
    y=get(y);
    if(x!=y)fa[y]=x;
}
struct edge{
    int a,p;
    //a记录当前的值,p记录位置 
}E[maxn];
bool cmp(edge a,edge b){
    return a.a<b.a;
}
bool outcmp(edge a,edge b){
    return a.p<b.p;
}
set<int> savenow;//存储每一次已经被用过的位置 
int cas[maxn];//记录上一次的排列顺序 
int main(){
    //freopen("T2.txt","r",stdin);
    init();
    n=read();k=read();
    for(register int i=1;i<=n;i++)E[i].a=read(),E[i].p=i;
    while(1){
        bool here=1;
        for(register int i=1;i<=n-k;i++){
            for(register int j=i+k;j<=n;j++){
                if(abs(E[i].a-E[j].a)==1)merge(i,j);
            }
        }
        for(register int i=1;i<=n;i++){
            int last_time=i;
            for(register int j=1;j<=n;j++){
                if(savenow.count(j))continue;
                if(get(E[i].p)==get(j)){
                    if(E[i].p>E[j].p){
                        swap(E[i].p,E[last_time].p);
                        swap(E[i].p,E[j].p);
                        last_time=j;
                    }
                }
            }
            savenow.insert(E[i].p);
            if(cas[E[i].p]!=E[i].a){
                cas[E[i].p]=E[i].a;
                here=0;
            }
        }
        if(here)break;
    }
    for(register int i=0;i<=n;i++)printf("%d ",cas[i]);
    return 0;
}

是的,这看似是一个简便又快捷的写法,这时再让我们抱着激动的心情来计算一下复杂度
算了。溜(事实上这个算法的复杂度是O(n!)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容

  • 你就是天边的一片云, 我伸出手, 轻轻抚摸, 以为可以将你把握。 悠然的,你飘荡着, 飘出我的手心, 逃离我的视线...
    程沐阅读 621评论 2 1
  • 方世平—10月6日分析 美国9月非农就业人数增加13.4万人,刷新2017年10月以来新低,市场预期增加18.8万...
    方世平阅读 157评论 0 0
  • 2015年9月认识你 可能是在10月,也可能是在习惯你的日子里,开始喜欢你 2017年5月31日,表白失败 你说...
    Free小记阅读 160评论 0 3