C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

全過去ログを検索

<< 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 >>
■62338  Re[1]: windows7 64bitで作成したExcelのエラー
□投稿者/ 魔界の仮面弁士 -(2011/10/04(Tue) 11:30:35)
    2011/10/04(Tue) 11:32:00 編集(投稿者)

    No62332 (雷瀬 さん) に返信
    > 分類:[VB.NET/VB2005 以降] 
    VB2〜VB6 専用掲示板にも同等の質問がありましたが、こちらでは VB.NET の質問なのですね?
    http://hpcgi1.nifty.com/MADIA/VBBBS/wwwlng.cgi?print+201110/11100002.txt


    > 「Windows7 64bitのExcel2007環境」
    > で動かすとエラーとなってしまいます。
    ・Excel 2007 の COM オブジェクトを、AnyCPU ビルドで呼び出していませんか?
    ・問題のファイルを、Excel 2010 32bit や Excel 2010 64bit で開いた時はどうなりますか?
    ・管理者モードで実行した場合も同じ結果になりますか?


    > どなたか対処法を知りませんでしょうか。
    Microsoft のサポート サービスを利用されては如何でしょう。
    http://www.microsoft.com/ja-jp/services/support.aspx
記事No.62332 のレス /過去ログ104より / 関連記事表示
削除チェック/

■62618  プログラムの練習問題でわからないことが
□投稿者/ 堀江伸一 -(2011/10/21(Fri) 15:44:36)

    分類:[C/C++] 

    2011/10/21(Fri) 15:52:32 編集(投稿者)
    2011/10/21(Fri) 15:52:28 編集(投稿者)

    http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0509
    勉強のためにリンク先問題をとこうとしているのですがなかなか解けずに困っております。
    どなたかアドバイスをいただけないでしょうか?


    一応答えがあり模範解答的な考え方はこちらです。
    http://www.ioi-jp.org/joi/2005/2006-ho-prob_and_sol/2006-ho-t5-review.html
    集合とか苦手なので良く分からなず模範解答を手本にためしに手探りで下記コードを書いたのですが、コード実行速度が遅すぎるというので不正解となってしまいます。
    公開されているジャッジデータで試すとコード自体は正しい答えを出しているので問題になるのは速度だけなのですが。
    模範解答の考え方の解説かコードの高速化の指摘を頂けたらと思います。


    #include<stdio.h>
    #include<map>
    #include<vector>
    struct col{
    //短冊に切ったシートのY座標上下
    int y1,y2;
    };

    void calcR(int& ansR,int& ansS,std::vector<col>& tate,std::map<int,int>& sheetIO) {
    //X列にあるシートの周長と面積を求める
    col t;
    std::map<int,int>::iterator it;
    tate.clear();
    it=sheetIO.begin();
    t.y1=(*it).first;
    int inOutCount=0;
    while(it!=sheetIO.end()){
    inOutCount+=(*it).second;
    if(inOutCount==0){
    t.y2=(*it).first;
    ansR+=(t.y2-t.y1)*2+2;//Y軸と平行に短冊に切ったシートの上下左右の周長
    ansS+=t.y2-t.y1;//面積
    tate.push_back(t);
    it++;
    if(it==sheetIO.end())break;
    t.y1=(*it).first;
    }else{
    it++;
    }
    }
    }
    void setMap(int n,int type){
    std::map<int,int> sheetIO[10002];//シートにsheetIO[x座標]。シートに入る出るの管理をするY座標は0から増えていく
    std::map<int,int> tempIO;
    int ioCount;
    int x1,y1,x2,y2,x,y;
    int maxX=0,minX=10001;
    std::map<int,int>::iterator it;
    for(int i=0;i<n;i++){
    scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
    x1++;//0列目はダミーとして使うので一列シートをずらす
    x2++;
    if(x1<minX)minX=x1;
    if(x2>maxX)maxX=x2;
    //シートを短冊状に切ってマップ上に重ねていく、
    //x座標を固定してY=0からY=10000までシートに入る出るをカウントしていく
    for(int x=x1;x<x2;x++){
    if(sheetIO[x].find(y1)==sheetIO[x].end()){

    sheetIO[x][y1]=1;
    }else{
    //シートが2枚以上重なった地点にはいるY座標
    sheetIO[x][y1]++;
    }
    if(sheetIO[x].find(y2)==sheetIO[x].end()){
    sheetIO[x][y2]=-1;
    }else{
    //シートから抜け出す地点
    sheetIO[x][y2]--;
    }
    }
    if(i>0 && i%50==0){
    //シートに入った出たの量が多くなるのでここで整理する
    //シートを短冊状にきってあるので一列のシートと見て重複部分を統合する。
    for(int x=minX;x<=maxX;x++){
    it=sheetIO[x].begin();
    if(it==sheetIO[x].end())continue;
    ioCount=0;
    tempIO.clear();
    tempIO[(*it).first]=1;
    while(it!=sheetIO[x].end()){
    ioCount+=(*it).second;
    if(ioCount==0){
    //シートに入った数と出た数が同じつまりシートから出た
    tempIO[(*it).first]=-1;
    it++;
    if(it==sheetIO[x].end())break;
    tempIO[(*it).first]=1;
    }else{
    it++;
    }
    }
    //データ更新
    sheetIO[x].clear();
    sheetIO[x].insert(tempIO.begin(),tempIO.end());
    }
    }
    }
    int ansR=0,ansS=0,old,now,p1,p2;//周長
    std::vector<col> tate[2];
    int yOld1,yOld2,yNow1,yNow2;
    //ここから先周長と面積を計算する。
    for(int x=minX;x<=maxX;x++){
    calcR(ansR,ansS,tate[x%2],sheetIO[x]);
    old=(x+1)%2;
    now=x%2;
    p1=p2=0;
    //一列ごとにシートのしかれた部分に出る入るを元に面積と周長を計算する。
    while(p2<tate[now].size() && p1<tate[old].size()){
    yOld1=tate[old][p1].y1;
    yOld2=tate[old][p1].y2;
    yNow1=tate[now][p2].y1;
    yNow2=tate[now][p2].y2;
    //隣の列Oldと今計算中の列nowでシートが接する部分があればそれを周長からひく。
    if(yOld1>=yNow2){
    p2++;
    }else if(yOld2<=yNow1){
    p1++;
    }else if(yOld2>=yNow2 && yOld1>=yNow1 && yOld1<=yNow2){
    ansR-=2*(yNow2-yOld1);
    p2++;
    }else if(yOld2>=yNow2 && yOld1<=yNow1){
    ansR-=2*(yNow2-yNow1);
    p2++;
    }else if(yOld2<=yNow2 && yOld1<=yNow1 && yOld2>=yNow1){
    ansR-=2*(yOld2-yNow1);
    p1++;
    }else if(yOld2<=yNow2 && yOld1>=yNow1){
    ansR-=2*(yOld2-yOld1);
    p1++;
    }
    }
    }
    //答えの出力
    if(type==2){
    printf("%d\n%d\n",ansS,ansR);
    }else{
    printf("%d\n",ansS);
    }
    }
    int main()
    {
    int n,type;
    scanf("%d %d",&n,&type);
    while(n!=0 || type!=0){
    setMap(n,type);
    scanf("%d %d",&n,&type);
    }
    }
親記事 /過去ログ105より / 関連記事表示
削除チェック/

■62650  Re[4]: プログラムの練習問題でわからないことが
□投稿者/ uso8mega -(2011/10/24(Mon) 15:22:53)
    追記に気付かなくて済みません。rssとか変更通知とかが無い場所は、定期的に監視する対象が基本決まっていますもので。

    >下記コードは計算量が安定する代わりにコード実行速度が遅めという欠点があります。
    擬似的なbitblt(メインメモリとVRAM間の転送)みたいな処理[temp→map]なので、遅いのは無理もありません。GPUにでも任せたくなる処理ですね。

    >模範解答の考え方の解説を頂けたらと思います。
    出力結果が正しいなら、JOIの解説は殆ど実行できている筈ですので特に問題は無いかと。
    あえて目立つ部分を補足するならば
    >集合とか苦手なので良く分からなず
    シートが多重重ねになっている部分を正しく処理できていれば、∪(論理和)とか特に気にすることはないでしょう。まぁsheetIOでのシート重ね差分の記録&tempIOによる一重化は少々冗長な気もしますが、データ的に分かり易くもありますし。
    >>入力をあらかじめ並べなおしておけば,さらに効率良く
    恐らく、入力ファイルの一グループn個分をまとめ読みしておいて、y1が小さくy2が大きい順にでも並べ替えておいてから処理した方が、シート重ね処理を簡便化し易いと思います。次処理シートの当てはめ位置の検索とか、次処理シートが処理済シートに完全に重なっているので追加不要になりがちとか。
    >>線形リスト
    std::listのことかな?恐らくシート重ね処理での煩雑な要素の追加・削除をできるだけ少なくしたいのだと思います。大メモリ領域の確保・解放・複写は比較的重くなりがちな処理ですし。OOPだと目立ちにくい所でコンストラクタ&デストラクタが大量に実行されたりして、更に重くなりがちですから。

    >このスレの最初のコードを高速化する
    済みませんあんまり興味が無かったんでコードは精査していないんですが、自分が作るとしたら恐らくシート重ね処理の中でシート重ね枚数差分情報のsheetIO&tempIOを介さずに直接std::vector<col> tate[10000/*X座標*/];を構築するように記述すると思います。ってかJOI解説もこれを線形リストで構築する前提で書いてあるように思えます。
    tate[]の中で、次処理シートが処理済シートに重なっていなければ単純挿入するだけですし、重なっていれば(ピッタリ隣接分も含む)重なっている範囲の全処理済シート群+次処理シートを1枚分にまとめて[y1=min(範囲内全y1), y2=max(範囲内全y2)]置き換えます。この置き換え処理が、線形リストだとかなり低コストに実行できそうです。
    sheetIO+tempIOでの処理だと、複数毎重ねては潰し 重ねては潰ししていて その都度Y軸方向にトレースかけているので、この部分の処理がネックになっていそうですし。

    すみませんが指摘できるのは現状ソレ位です。JOI2006の問題5の入力8/9は10000四角もあるのに持ち時間が60秒?で1四角当たり6msec以内で処理せよってのは少々ハードル高めかもしれません。
記事No.62618 のレス /過去ログ105より / 関連記事表示
削除チェック/

■62731  Re[6]: プログラムの練習問題をゆっくりと考えていきます
□投稿者/ 堀江伸一 -(2011/10/31(Mon) 08:46:09)
    新しい質問に移行します。
    http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0172
    リンク先問題を解くコードで悩んでいます。
    部屋の明りをのスイッチを入れたり消したりしながら部屋から部屋へ移動し、最後の部屋で全ての部屋の電気を消してかえれるか。
    最短手順を求めよという問題です。
    
    
    現在の解法は以下のとおりとなっています。
    部屋から部屋へ移動する操作を深さ優先探索で求めます。
    もし真っ暗な部屋に入ったら、過去の部屋にさかのぼってその部屋のスイッチを入れていたことにして先に進みます。
    
    探索中は今まで入った部屋にあったスイッチをOffにできる部屋として全て覚えておき、その後スイッチの消せる部屋に入ったらその部屋のスイッチを消してはいけないので、ここまでの道の途中で消すことが出来ない部屋として保存しておきます。
    
    このコードを5倍高速化出来たらたぶん合格できるのですが。
    どなたかコードの改善点をご指摘いただけたらと思います。
    
    
    一応今考えているのはルートの記憶を担当している変数
    void rootSearch(rootMemo nowRoot
    を
    void rootSearch(rootMemo& nowRootにしてコピーのコストを低減する小手先の方法のみです。
    
    #include<stdio.h>
    #include<queue>
    #include<string.h>
    #include<vector>
    #include<set>
    
    
    
    struct switchMemo{
    	//ある部屋で操作したスイッチの記録
    	char onOf;
    	int roomNo;
    	bool operator<(const switchMemo& s)const{
    		return roomNo<s.roomNo;
    	}
    };
    struct rootMemo{
    	int turn,lightState,nowRoomNo,lightOffMemo;//,roomsMemo
    	//通ってきた部屋順と操作したスイッチを記録する
    	std::vector<std::set<switchMemo> > switchsMemo;
    	std::vector<int> root;
    };
    
    struct stateMemo{
    	//同じ部屋で同じライトの状態でないかを記録し無限ループを防ぐ
    	int nowRoomNo,lightState,lightOffMemo,turn;//roomsMemo;
    	bool operator<(const stateMemo& sm)const{
    		if(nowRoomNo!=sm.nowRoomNo)return nowRoomNo<sm.nowRoomNo;
    		//if(roomsMemo!=sm.roomsMemo)return roomsMemo<sm.roomsMemo;
    		if(lightOffMemo!=sm.lightOffMemo)return lightOffMemo<sm.lightOffMemo;
    		return lightState<sm.lightState;
    	}
    	void set(rootMemo& nowRoot){
    		nowRoomNo=nowRoot.nowRoomNo;
    		lightState=nowRoot.lightState;
    		//roomsMemo=nowRoot.roomsMemo;
    		lightOffMemo=nowRoot.lightOffMemo;
    		turn=nowRoot.turn; 
    	}
    };
    
    //グローバル変数はここに集める
    const int roomSize=16;
    const char SwitchOn='n',SwitchOff='f',RoomMove='m';
    std::set<switchMemo> dsets;
    int n,m;
    bool goalOK=false,allOfOK=false;
    rootMemo ansRoot;
    //ここまで
    
    
    void print(rootMemo& ansRoot){
    	//答えの出力
            std::set<switchMemo>::iterator it;
    	printf("You can go home in %d steps.\n",ansRoot.turn);
    	for(unsigned int i=0;i<ansRoot.root.size();i++){
    		if(i!=0){
    			printf("Move to room %d.\n",ansRoot.root[i]);
    		}
    		it=ansRoot.switchsMemo[i].begin();
    		while(it!=ansRoot.switchsMemo[i].end()){
    			if((*it).onOf==SwitchOn){
    				printf("Switch on room %d.\n",(*it).roomNo);
    			}else{
    				printf("Switch off room %d.\n",(*it).roomNo);
    			}
    			it++;
    		}
    	}
    }
    
    
    bool backSwitchOn(rootMemo& rm,std::vector<int> roomSwitchs[roomSize]){
    	unsigned int t1;
    	int nowRoomNo=rm.nowRoomNo;
    	//ある部屋に入った時その部屋が真っ暗なら過去にさかのぼってスイッチのあった部屋でスイッチを入れてたことにする。
    	//スイッチが見つからず部屋に入ることが不可能ならfalseを返す
    	switchMemo sm;
    	sm.roomNo=nowRoomNo;
    	sm.onOf=SwitchOn;
    	for(int i=0;i<rm.root.size()-1;i++){
    		t1=roomSwitchs[rm.root[i]].size();
    		for(int j=0;j<t1;j++){
    			if(nowRoomNo==roomSwitchs[rm.root[i]][j]){
    				rm.lightState|=(1<<(nowRoomNo-1));
    				rm.switchsMemo[i].insert(sm);
    				rm.turn++;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    bool backSwitchAllOf(rootMemo& rm,std::vector<int> roomSwitchs[roomSize]){
    	int lightState=rm.lightState,nowRoom,nowSwitchBit,nowSwitch;
    	//最後の部屋に入った時過去にさかのぼり消しても問題のない部屋を全て消していたことにする。
    	switchMemo sm;
    	sm.onOf=SwitchOff;
    	bool onOfOK[roomSize];
    	memset(onOfOK,true,roomSize);
    	std::set<switchMemo>::iterator it;
    	for(int i=rm.root.size()-1;i>=0;i--){
    		nowRoom=rm.root[i];
    		onOfOK[nowRoom]=false;
    		for(unsigned int j=0;j<roomSwitchs[nowRoom].size();j++){
    			nowSwitch=roomSwitchs[nowRoom][j];
    			nowSwitchBit=(1<<(nowSwitch-1));
    			if((lightState&nowSwitchBit)!=0 && onOfOK[nowSwitch]==true){
    				lightState=(lightState&(~nowSwitchBit));
    				sm.roomNo=nowSwitch;
    				rm.switchsMemo[i].insert(sm);
    				rm.turn++;
    			}
    		}
    	}
    	if(lightState==(1<<(n-1)))return true;
    	return false;
    }
    
    
    void rootSearch(rootMemo nowRoot,int nextRoom,
    		bool roomConnect[roomSize][roomSize],std::vector<int> roomSwitchs[roomSize],std::set<stateMemo>& statesMemo){
    		//深さ優先探索で部屋から部屋へ移動する
    
    		//見つかった帰宅ルートより長くなったら別の探索へ
    		if(ansRoot.turn<nowRoot.turn) return;
    		//ゴール出来たら過去にさかのぼり電気を消せる部屋を全て消す
                    if(nowRoot.nowRoomNo==n && backSwitchAllOf(nowRoot,roomSwitchs)==true){
    			if(ansRoot.turn>nowRoot.turn){
    				ansRoot=nowRoot;
    				allOfOK=true;
    				return;
    			}
    		}else if(nowRoot.nowRoomNo==n){
    			goalOK=true;
    		}
    		
    		stateMemo nowState;
    		nowRoot.nowRoomNo=nextRoom;
    		nowRoot.root.push_back(nowRoot.nowRoomNo);
    		nowRoot.switchsMemo.push_back(dsets);
    		nowRoot.turn++;
    
    		if((nowRoot.lightState&(1<<(nowRoot.nowRoomNo-1)))!=0){
    			//明るい部屋にそのまま移動
    		}else if(backSwitchOn(nowRoot,roomSwitchs)){
    			//もし部屋が暗かったら過去に辿った部屋でスイッチをつけていたことにして移動する
    		}else{
    			//過去にさかのぼってもスイッチを入れられなかったら
    			return ;
    		}
    		
    
    		for(unsigned int i=0;i<roomSwitchs[nowRoot.nowRoomNo].size();i++){
    			nowRoot.lightOffMemo|=(1<<(roomSwitchs[nowRoot.nowRoomNo][i]-1));//消せるスイッチのリスト
    		}
    		nowRoot.lightOffMemo&=(~(1<<(nowRoot.nowRoomNo-1))); //今いる部屋は消せないので元に戻す
    		nowState.set(nowRoot);
                    //過去にさかのぼって消せる部屋のリストと今のライトのOnOff状態と今の部屋が同じになった状態がないかチェック
    		if(statesMemo.find(nowState)==statesMemo.end()){
    			statesMemo.insert(nowState);
    		}else{
    			int tTurn=(*statesMemo.find(nowState)).turn ;
    			if(tTurn>nowState.turn){
    				statesMemo.erase(nowState);
    				statesMemo.insert(nowState); 
    			}else{
    				return;
    			}
    		}
    		for(int i=1;i<=n;i++){
    			if(roomConnect[nextRoom][i]){
    				rootSearch(nowRoot,i,roomConnect,roomSwitchs,statesMemo);
    			}
    		}
    }
    
    
    void setData(){
    	int p1,p2,roomLightState;//1bitずつ管理;
    	bool roomConnect[roomSize][roomSize];
    	
    	std::vector<int> roomSwitchs[roomSize];
    	
    	
    	
    	memset(roomConnect,false,roomSize*roomSize);
    	
    	
    	for(int i=0;i<m;i++){
    		scanf("%d %d",&p1,&p2);
    		roomConnect[p1][p2]=roomConnect[p2][p1]=true;
    	}
    	
    	roomLightState=0;//ライトのオンオフ管理
    	for(int i=1;i<=n;i++){
    		scanf("%d",&p1);
    		roomLightState|=p1==0?0:1<<(i-1);
    	}
    	int s,t;
    	for(int i=1;i<=n;i++){
    		scanf("%d",&s);
    		for(int j=0;j<s;j++){
    			scanf("%d",&t);
    			if(i!=t){
    				roomSwitchs[i].push_back(t);
    			}
    		}
    	}
    	//データの読み込み終わり
    	//ここから深さ優先探索で部屋の移動をシミュレートするための初期データセット
    	
    	std::set<stateMemo> statesMemo;
    	
    	stateMemo nowState;
    	rootMemo nowRoot,tempRoot;
    	
    	
    	
    	nowRoot.nowRoomNo=1;
    	nowRoot.lightState=roomLightState;
    	nowRoot.turn=-1;
    	nowRoot.lightOffMemo=0;
    	
    	ansRoot.turn=1000000000;
    	int nowRoomNo;
    	
    	
    	bool moveOKs[roomSize];
    	goalOK=allOfOK=false;
    	
    	memset(moveOKs,true,roomSize);
    	//深さ優先探索
    	rootSearch(nowRoot,1,roomConnect,roomSwitchs,statesMemo);
    
    	if(allOfOK==true){
    		print(ansRoot);
    	}else if(goalOK==true){
    		printf("You can not switch off all lights.\n");
    	}else{
    		printf("Help me!\n");
    	}
    }
    
    int main(){
    	while(1){
    		scanf("%d %d",&n,&m);
    		if(n==0 && m==0)break;
    		setData();
    	}
    }
    
記事No.62667 のレス /過去ログ105より / 関連記事表示
削除チェック/

■62734  Re[9]: プログラムの練習問題をゆっくりと考えていきます
□投稿者/ 堀江伸一 -(2011/10/31(Mon) 10:53:03)
    2011/10/31(Mon) 10:54:23 編集(投稿者)

    やってみたら小手先のテクニックで解決できました。


    解法
    部屋数が少ないために一見計算量が小さく見えますが、部屋の明かりの状態が2^部屋数乗通りあるために見た眼よりも計算量が多い問題です。
    意外と組み合わせ数が多くグラフに翻訳しても頂点数が「部屋の数*明りの状態^部屋数」ということになりグラフでも簡単には解けません。
    また正解ルートを保持する必要があるためメモリ使用量制限32MB(個の問題は32Mb以上メモリを使ってはいけない)にも引っかかることになります。
    このためグラフの手法も幅優先探索も使えません。

    そこで手順数が最小になる手順になるルールに従ってのみ移動するという深さ優先探索の手法が有効になります。
    解法は以下のとおりとなります。
    部屋から部屋へ移動する操作を深さ優先探索で求めます。

    移動中あった部屋のスイッチをON、Offできるスイッチとして覚えておきます。

    探索中は今まで入った部屋にあったスイッチを全て覚えておきます。
    これはスイッチをONOFFにできる部屋として記憶します。

    移動中さかのぼってONOFF出来る部屋に入ったとします。
    するとその部屋のスイッチは過去において消してはいけないので、消すことが出来ないスイッチなのでOnOff履歴からはずします。
    もし真っ暗な部屋に入ったら、過去の部屋にさかのぼってその部屋のスイッチを入れていたことにして先に進みます。

    後はこれを深さ優先探索として実装します。


    //練習問題であるためいくつかの変数名を縮めています。


    #include<stdio.h>
    #include<queue>
    #include<string.h>
    #include<vector>
    #include<set>
    struct switchMemo{
    //ある部屋で操作したスウィッチの記録
    char onOf;
    int roomNo,turn;
    bool operator<(const switchMemo& s)const{
    return roomNo<s.roomNo;
    }
    };
    struct rootMemo{
    int turn,lightState,nowRoomNo,lightOffMemo;//
    //通ってきた部屋順と操作したスウィッチを記録する
    std::vector<std::set<switchMemo> > switchsMemo;
    std::vector<int> root;
    };
    struct stateMemo{
    //同じ部屋で同じライトの状態でないかを記録し無限ループを防ぐ
    int nowRoomNo,lightState,lightOffMemo,turn;//roomsMemo;
    bool operator<(const stateMemo& sm)const{
    if(nowRoomNo!=sm.nowRoomNo)return nowRoomNo<sm.nowRoomNo;
    //if(roomsMemo!=sm.roomsMemo)return roomsMemo<sm.roomsMemo;
    if(lightOffMemo!=sm.lightOffMemo)return lightOffMemo<sm.lightOffMemo;
    return lightState<sm.lightState;
    }
    void set(rootMemo& nowRoot){
    nowRoomNo=nowRoot.nowRoomNo;
    lightState=nowRoot.lightState;
    //roomsMemo=nowRoot.roomsMemo;
    lightOffMemo=nowRoot.lightOffMemo;
    turn=nowRoot.turn;
    }
    };
    //グローバル変数はここに集める
    const int roomSize=16;
    const char SwitchOn='n',SwitchOff='f',RoomMove='m';
    std::set<switchMemo> dsets;
    int n,m;
    bool goalOK=false,allOfOK=false;
    rootMemo ansRoot;
    //ここまで
    void print(rootMemo& ansRoot){
    std::set<switchMemo>::iterator it;
    printf("You can go home in %d steps.\n",ansRoot.turn);
    for(unsigned int i=0;i<ansRoot.root.size();i++){
    if(i!=0){
    printf("Move to room %d.\n",ansRoot.root[i]);
    }
    it=ansRoot.switchsMemo[i].begin();
    while(it!=ansRoot.switchsMemo[i].end()){
    if((*it).onOf==SwitchOn){
    printf("Switch on room %d.\n",(*it).roomNo);
    }else{
    printf("Switch off room %d.\n",(*it).roomNo);
    }
    it++;
    }
    }
    }
    bool backSwitchOn(rootMemo& rm,std::vector<int> roomSwitchs[roomSize],switchMemo& bs){
    unsigned int t1;
    int nowRoomNo=rm.nowRoomNo;
    //ある部屋に入った時その部屋が真っ暗なら過去にさかのぼってスイッチのあった部屋でスイッチを入れてたことにする。
    //スイッチが見つからず部屋に入ることが不可能ならfalseを返す
    switchMemo sm;
    bs.roomNo=sm.roomNo=nowRoomNo;
    bs.onOf=sm.onOf=SwitchOn;
    for(int i=0;i<rm.root.size()-1;i++){
    t1=roomSwitchs[rm.root[i]].size();
    for(int j=0;j<t1;j++){
    if(nowRoomNo==roomSwitchs[rm.root[i]][j]){
    rm.lightState|=(1<<(nowRoomNo-1));
    rm.switchsMemo[i].insert(sm);
    rm.turn++;
    bs.turn=i;
    return true;
    }
    }
    }
    return false;
    }
    bool backSwitchAllOf(rootMemo rm,std::vector<int> roomSwitchs[roomSize]){
    int lightState=rm.lightState,nowRoom,nowSwitchBit,nowSwitch;
    //最後の部屋に入った時過去にさかのぼり消しても問題のない部屋を全て消していたことにする。
    switchMemo sm;
    sm.onOf=SwitchOff;
    bool onOfOK[roomSize];
    memset(onOfOK,true,roomSize);
    std::set<switchMemo>::iterator it;
    for(int i=rm.root.size()-1;i>=0;i--){
    nowRoom=rm.root[i];
    onOfOK[nowRoom]=false;
    for(unsigned int j=0;j<roomSwitchs[nowRoom].size();j++){
    nowSwitch=roomSwitchs[nowRoom][j];
    nowSwitchBit=(1<<(nowSwitch-1));
    if((lightState&nowSwitchBit)!=0 && onOfOK[nowSwitch]==true){
    lightState=(lightState&(~nowSwitchBit));
    sm.roomNo=nowSwitch;
    rm.switchsMemo[i].insert(sm);
    rm.turn++;
    }
    }
    }
    if(lightState==(1<<(n-1))){
    if(ansRoot.turn>rm.turn){
    ansRoot=rm;
    allOfOK=true;
    }
    return true;
    }
    return false;
    }
    void remove(rootMemo& nowRoot,switchMemo& backOnSwitch,stateMemo& backState){
    //この探索ルートは失敗なので元に戻す
    nowRoot.root.pop_back();
    nowRoot.nowRoomNo =backState.nowRoomNo;
    nowRoot.lightState =backState.lightState;
    nowRoot.lightOffMemo =backState.lightOffMemo;
    nowRoot.turn =backState.turn;
    //スイッチを操作したが、過去と同じ状態になった
    if(backOnSwitch.turn!=-1){
    nowRoot.switchsMemo[backOnSwitch.turn].erase(backOnSwitch);
    }
    }
    void rootSearch(rootMemo& nowRoot,int nextRoom,
    bool roomConnect[roomSize][roomSize],std::vector<int> roomSwitchs[roomSize],std::set<stateMemo>& statesMemo);
    if(ansRoot.turn<=nowRoot.turn) return;
    if(nowRoot.nowRoomNo==n){
    int offs=nowRoot.lightOffMemo|(1<<(n-1));
    if((nowRoot.lightState&offs)==nowRoot.lightState && backSwitchAllOf(nowRoot,roomSwitchs)==true){
    }else{
    goalOK=true;
    }
    }
    stateMemo nowState,backState;
    switchMemo backSwitch;//もし駄目だった場合元に戻す
    backSwitch.turn=-1;
    backState.set(nowRoot);//失敗した場合元に戻すための記録
    nowRoot.nowRoomNo=nextRoom;
    nowRoot.root.push_back(nowRoot.nowRoomNo);
    while(nowRoot.root.size()>nowRoot.switchsMemo.size()){
    nowRoot.switchsMemo.push_back(dsets);
    }
    if((nowRoot.lightState&(1<<(nowRoot.nowRoomNo-1)))!=0){
    //明るい部屋にそのまま移動
    }else if(backSwitchOn(nowRoot,roomSwitchs,backSwitch)){
    //もし部屋が暗かったら過去に辿った部屋でスイッチをつけていたことにして移動する
    }else{
    remove(nowRoot,backSwitch,backState);
    return ;
    }
    nowRoot.turn++;//移動したのでターン数を増やす

    for(unsigned int i=0;i<roomSwitchs[nowRoot.nowRoomNo].size();i++){
    nowRoot.lightOffMemo|=(1<<(roomSwitchs[nowRoot.nowRoomNo][i]-1));//消せるスイッチのリスト
    }
    nowRoot.lightOffMemo&=(~(1<<(nowRoot.nowRoomNo-1))); //今いる部屋は消せないので元に戻す
    nowState.set(nowRoot);
    if(statesMemo.find(nowState)==statesMemo.end()){
    statesMemo.insert(nowState);
    }else{
    int tTurn=(*statesMemo.find(nowState)).turn ;
    if(tTurn>nowState.turn){
    statesMemo.erase(nowState);
    statesMemo.insert(nowState);
    }else{
    remove(nowRoot,backSwitch,backState);
    return;
    }
    }
    for(int i=1;i<=n;i++){
    if(roomConnect[nextRoom][i]){
    rootSearch(nowRoot,i,roomConnect,roomSwitchs,statesMemo);
    }
    }
    remove(nowRoot,backSwitch,backState);
    }
    void setData(){
    int p1,p2,roomLightState;//1bitずつ管理;
    bool roomConnect[roomSize][roomSize];
    std::vector<int> roomSwitchs[roomSize];
    memset(roomConnect,false,roomSize*roomSize);
    for(int i=0;i<m;i++){
    scanf("%d %d",&p1,&p2);
    roomConnect[p1][p2]=roomConnect[p2][p1]=true;
    }
    roomLightState=0;//ライトのオンオフ管理
    for(int i=1;i<=n;i++){
    scanf("%d",&p1);
    roomLightState|=p1==0?0:1<<(i-1);
    }
    int s,t;
    for(int i=1;i<=n;i++){
    scanf("%d",&s);
    for(int j=0;j<s;j++){
    scanf("%d",&t);
    if(i!=t){
    roomSwitchs[i].push_back(t);
    }
    }
    }
    //データの読み込み終わり
    //ここから深さ優先探索で部屋の移動をシミュレートするための初期データセット
    std::set<stateMemo> statesMemo;
    stateMemo nowState;
    rootMemo nowRoot,tempRoot;
    nowRoot.nowRoomNo=1;
    nowRoot.lightState=roomLightState;
    nowRoot.turn=-1;
    nowRoot.lightOffMemo=0;
    ansRoot.turn=1000000000;
    int nowRoomNo;
    goalOK=allOfOK=false;
    //深さ優先探索
    rootSearch(nowRoot,1,roomConnect,roomSwitchs,statesMemo);
    if(allOfOK==true){
    print(ansRoot);
    }else if(goalOK==true){
    printf("You can not switch off all lights.\n");
    }else{
    printf("Help me!\n");
    }
    }
    int main(){
    while(1){
    scanf("%d %d",&n,&m);
    if(n==0 && m==0)break;
    setData();
    }
    }
記事No.62667 のレス /過去ログ105より / 関連記事表示
削除チェック/

■62923  Re[19]: プログラムの練習問題をゆっくりと考えていきます
□投稿者/ 堀江伸一 -(2011/11/10(Thu) 15:18:08)
    2011/11/10(Thu) 15:32:36 編集(投稿者)
    2011/11/10(Thu) 15:31:33 編集(投稿者)

    ありがとうございます。
    shuさんのはちょっと難しそうなのでプリントして今からよく考えてみます。


    私が思いついた解法としては。
    まずこの問題は動的計画法もしくは特定のデータを優先して処理することで解決できる問題のようです。
    正答者データにあるコード実行時間を考慮すると線形的な解はなさそうですね。


    計算量の安定する動的計画法を採用します。

    まず、組み合わせ数を減らします。

    ある切断方法がある場合切断位置をA1,A5,A4と切断するのも
    A1 A4 A5と切断するのもタイムに変わりはありません。

    よって左端から切断していくこととして組み合わせ数を減らします。

    次に、左端から切断していった場合二人をAさんBさんとします。
    切断したものを左から見てAさんBさんの分配を見ていくと
    ABABA,,,という順番でしか分けられないことが判明します。

    もし
    ABBAのような分配があればBBは切断する必要がありません。
    よってABAB、、、のような配置となります。

    左から切断していってAさんBさんと切断した端から二人に分けていった場合r個目の切断位置がAiだったとします。

    するとAiまでで何か所どこを切断したかという情報は必要なくなります。

    必要な情報はAさんが何個でBさんが何個で今どの部分の切断箇所を分離したかという情報とここまでの切断タイムと次の切断をもらうのがAさんかBさんかだけが重要となります。

    @Ai個目を切断したときAさんがK個でBさんがi-k個でタイムはtで次の切断をもらうのがAさんかBさんか。

    後は@が同じ条件になる別の切り方の中で一番タイムの短い切り方以外残す必要がありません。
    動的計画法で片が付き計算量は大雑把に見積もって5000*10000*2の1億回、実際はもう少し減らせるまで圧縮できます。
    この計算回数はぎりぎり現実的なタイムで合格できそうです。

    この発想の場合思考力と分析力さえあれば高校生でも解ける問題であることが判明しました。

    後はコードを書いてこの発想が正しいか試してみるだけです。
記事No.62667 のレス /過去ログ105より / 関連記事表示
削除チェック/

■62928  Re[20]: プログラムの練習問題をゆっくりと考えていきます
□投稿者/ 堀江伸一 -(2011/11/10(Thu) 17:45:41)
    上記の考え方をそのまま実装してみたところコード実行速度5位メモリ使用量低で正答できました。
    ここから先の高速化とかはあまり考えてないので。
    もし高速化できそうなところがあったらご指摘ください。
    
    
    #include<stdio.h>
    #include<string.h>
    
    const int A=0;//二人をAさんBさんとする
    const int B=1;
    
    void setData(int n){
    	int memo[2][5002];//[次にもらうのがAさん=0 Bさん=1][Aさんがここまででもらった個数]=最小切断時間
    	int next[2][5002];//次の切断箇所の検討
    	int cutTimes[10001];//切断時間
    	int cutTime,herf=n/2,nowTime;
    	int up;
    
    	for(int i=0;i<n-1;i++)scanf("%d",&cutTimes[i]);
    	
    	memset(memo,127,sizeof(memo));//足される切断秒数は10000なのでオーバーフローしない
    	memo[A][1]=0;//計算しやすいようAさんが1個目を取得した状態から始める
    	
    	for(int turn=0;turn<n-1;turn++){
    		memset(next,127,sizeof(next));//ダミーデータ
    		cutTime=cutTimes[turn];//切断箇所をずらしていく
    
    		up=turn+1>herf?herf:turn+1;//上限
    		for(int k=1;k<=up;k++){
    			nowTime=memo[A][k];//Aさん
    			
    			//切断せずAさんが続けてもらう
    			next[A][k+1]=nowTime;
    			
    			//切断して次はBさんがもらう
    			next[B][k]=nowTime+cutTime;
    		}
    		for(int k=1;k<=up;k++){
    			//Bさんの番
    			nowTime=memo[B][k];
    			//Bさんが続けてもらう
    			next[B][k]=next[B][k]>nowTime?nowTime:next[B][k];
    			
    			//Aさんがもらう
    			nowTime+=cutTime;
    			next[A][k+1]=next[A][k+1]>nowTime?nowTime:next[A][k+1];
    		}
    		memcpy(memo,next,sizeof(next));
    	}
    	nowTime=memo[A][herf]>memo[B][herf]?memo[B][herf]:memo[A][herf];
    	
    	printf("%d\n",nowTime);
    }
    
    int main(){
    	int n;
    	scanf("%d",&n);
    	setData(n);
    	while(scanf("%d",&n)!=EOF){
    	}
    }
記事No.62667 のレス /過去ログ105より / 関連記事表示
削除チェック/

■62957  Re[25]: プログラムの練習問題をゆっくりと考えていきます
□投稿者/ 堀江伸一 -(2011/11/13(Sun) 10:44:41)
    問題は4分割目あたりですね。

    2分割の真ん中を切断するタイムT2が10000という最大値で3分割の切断時間最小値がT3とします。

    切断ポイントAiだけを考慮すると、3分割でタイムだけで検証すると5000*2500個程度の検証が必要になります。
    shuさんの方法そのままだと分割場所の情報がないので切断したものを二人に分けられるかの検証がその後に必要になります

    3分割の検証中で見つかった最小値でT3を更新しT3より大きな組み合わせは検証しないとしても組み合わせ数が大きなままである可能性は高いですね。

    もし3分割で最小値T3が決まったとします。

    4分割で何通りになるかです。
    4分割でどの程度期待できるかはわかりませんが。

    2500*1250*625=2億通り程度になるのではないでしょうか?
    これに切断ポイントが正しく2等分しているかの検証を考慮に入れないといけません。

    5分割だともっと計算はひどいことになりそうです。

    もしかしたら最小タイムの収束が非常に早く実際はうまくいくのかもしれませんが、計算量の見積もりがとても困難で不安定なのではないでしょうか?
記事No.62667 のレス /過去ログ105より / 関連記事表示
削除チェック/

■63154  Re[1]: C#でwsfファイルを実行する
□投稿者/ 魔界の仮面弁士 -(2012/07/26(Thu) 20:16:07)
    No63148 (asa さん) に返信
    > C#内でwsf内の関数を実行して返り値を得るプログラムを作成したいのですが可能でしょうか。
    
    wsf ではなく、wsc なら可能なのですけれどね。
    
    
    【C:\temp\test.wsc】
    
    <?xml version="1.0" encoding="utf-8"?>
    <package>
    <component>
    
    <public>
      <method name="ToYMD">
        <parameter name="dt" />
      </method>
    
      <property name="Today">
        <get />
      </property>
    </public>
    
    <script language="VBScript"><![CDATA[
    Option Explicit
    
    Function ToYMD(ByVal dt)
        ToYMD = Year(dt) * 10000 + Month(dt) * 100 + Day(dt)
    End Function
    
    Function get_Today()
        get_Today = Date
    End Function
    
    ]]></script>
    
    </component>
    </package>
    
    
    【C#】
    
    var file = @"C:\temp\test.wsc";
    dynamic wsc = Microsoft.VisualBasic.Interaction.GetObject("script:" + file);
    
    dynamic result;
    
    result = wsc.ToYMD(DateTime.Now);
    Console.WriteLine(result);
    
    result = wsc.Today;
    Console.WriteLine(result);
記事No.63148 のレス /過去ログ106より / 関連記事表示
削除チェック/

■63210  SmtpClientでの特定メアド宛メール送信でエラー
□投稿者/ ニーチェ -(2012/08/06(Mon) 11:47:03)

    分類:[VB.NET/VB2005 以降] 

    こんにちは。
    System.Net.Mail.SmtpClientを使ってメール送信をしているのですが、特定のメールアドレスに対して以下のエラーが発生します。

    「System.Net.Mail.SmtpFailedRecipientException: メールボックス名は許可されていません。 サーバーの応答: 5.3.0 <xxxx@xxxx.de>... DENY」

    ここで、"xxxx@xxxx.de"は送信エラーの発生するToメールアドレスで、".de"というドイツドメインのメールアドレスでした。
    その他のドメイン(".jp"・".co.jp"・".ne.jp"・".net"・".com")のメールアドレスについては、同じ方法で特に問題なくメール送信できています。
    たまたまエラーとなったメールアドレスが".de"だったので、国が関係あるのかどうなのか全く分かりません。
    このエラーの原因として、何か情報をお持ちの方はいらっしゃいますでしょうか?

    一応、ソースを以下に提示します。
    (Imports System.Net.Mailが記載されている前提とします。)

    Dim msg As New MailMessage
    Dim alv As AlternateView
    Dim sc As New System.Net.Mail.SmtpClient()
    Dim mai As MailAddressInfo

    msg.From = New MailAddress(Fromアドレス)
    msg.To.Add(New MailAddress(Toアドレス))
    msg.Subject = (エンコードされたSubject)
    alv = AlternateView.CreateAlternateViewFromString(本文テキスト, _
    System.Text.Encoding.GetEncoding(50220), _
    System.Net.Mime.MediaTypeNames.Text.Plain)

    alv.TransferEncoding = System.Net.Mime.TransferEncoding.SevenBit
    msg.AlternateViews.Add(alv)

    sc.Host = (ホスト)
    sc.Credentials = New System.Net.NetworkCredential(ユーザー, パスワード)
    sc.EnableSsl = False
    sc.Timeout = 100000
    sc.Send(msg)

    どうぞ宜しくお願い致します。
親記事 /過去ログ106より / 関連記事表示
削除チェック/

■63346  vb.netにおけるソケット通信
□投稿者/ ma-3 -(2012/08/17(Fri) 18:23:01)

    分類:[VB.NET/VB2005 以降] 

    vb.net2005を使用しています。

    サイトを参考にTCPクライアント・サーバープログラムを作成しています。
    ローカルネットワーク内ではサーバとクライアントともに正常に動作しますが、ローカルでなくなると正常に動作しません。

    ---サーバ側---
    http://homepage2.nifty.com/nonnon/SoftSample/CS.NET/SampleTcpIpSvr.html
    上記のサイトを参考にプログラムを作成
    ポート80,10000を開放
    グローバルIPアドレスでドメイン名を取得

    サーバ側のアプリケーションを稼働した後、ネット上のポート確認ツールなどにて、ポートが正常に解放されていることを確認。
    また、ping確認も正常。
    ---クライアント側---
    http://homepage2.nifty.com/nonnon/SoftSample/CS.NET/SampleTcpIp.html
    上記のサイトを参考にプログラムを作成
    サーバプログラムがあるネットワークには所属していない外部のクライアントです。
    Try
    '//クライアントのソケットを用意
    client = New System.Net.Sockets.TcpClient("ドメイン名", Int32.Parse("10000"))
    '//サーバからのデータを受信するループをスレッドで処理
    threadClient = New Thread(New ThreadStart(AddressOf ClientListen))
    threadClient.Start()
    Listbox1.Items.Add("サーバに接続しました:")
    Return True
    Catch ex As Exception
    Listbox1.Items.Add("クライアント接続エラー:" + ex.Message.ToString())
    Return False
    End Try
    実行すると、「対象のコンピュータによって拒否されたため接続できませんでした」と表示されエラーになります。
     また、ポート番号を80にして接続を試みたところ、正常に接続ができました。
     ルータの設定による10000ポートの割り振りやファイヤーオールの設定は行いましたが解決できません。

     解決策やアドバイスがありましたら、どうかご教授ください。
親記事 /過去ログ106より / 関連記事表示
削除チェック/

■63347  Re[1]: vb.netにおけるソケット通信
□投稿者/ ma-3 -(2012/08/17(Fri) 21:52:40)
    No63346 (ma-3 さん) に返信
    > vb.net2005を使用しています。
    >
    > サイトを参考にTCPクライアント・サーバープログラムを作成しています。
    > ローカルネットワーク内ではサーバとクライアントともに正常に動作しますが、ローカルでなくなると正常に動作しません。
    >
    > ---サーバ側---
    > http://homepage2.nifty.com/nonnon/SoftSample/CS.NET/SampleTcpIpSvr.html
    > 上記のサイトを参考にプログラムを作成
    > ポート80,10000を開放
    > グローバルIPアドレスでドメイン名を取得
    >
    > サーバ側のアプリケーションを稼働した後、ネット上のポート確認ツールなどにて、ポートが正常に解放されていることを確認。
    > また、ping確認も正常。
    > ---クライアント側---
    > http://homepage2.nifty.com/nonnon/SoftSample/CS.NET/SampleTcpIp.html
    > 上記のサイトを参考にプログラムを作成
    > サーバプログラムがあるネットワークには所属していない外部のクライアントです。
    > Try
    > '//クライアントのソケットを用意
    > client = New System.Net.Sockets.TcpClient("ドメイン名", Int32.Parse("10000"))
    > '//サーバからのデータを受信するループをスレッドで処理
    > threadClient = New Thread(New ThreadStart(AddressOf ClientListen))
    > threadClient.Start()
    > Listbox1.Items.Add("サーバに接続しました:")
    > Return True
    > Catch ex As Exception
    > Listbox1.Items.Add("クライアント接続エラー:" + ex.Message.ToString())
    > Return False
    > End Try
    > 実行すると、「対象のコンピュータによって拒否されたため接続できませんでした」と表示されエラーになります。
    >  また、ポート番号を80にして接続を試みたところ、正常に接続ができました。
    >  ルータの設定による10000ポートの割り振りやファイヤーオールの設定は行いましたが解決できません。
    >
    >  解決策やアドバイスがありましたら、どうかご教授ください。
記事No.63346 のレス / END /過去ログ106より / 関連記事表示
削除チェック/

■64410  Re[2]: デザイナで配置したTextBoxでエラーが出てしまう
□投稿者/ くまん -(2012/11/30(Fri) 17:42:23)
    2012/11/30(Fri) 17:46:43 編集(投稿者)
    2012/11/30(Fri) 17:44:18 編集(投稿者)
    2012/11/30(Fri) 17:43:25 編集(投稿者)
    2012/11/30(Fri) 17:42:53 編集(投稿者)

    2人方ありがとうございます。
    コントロールの使用方法については理解しているつもりなので
    その辺りに関しては大丈夫です。

    自分でいろいろと調べてみた結果、
    なぜか実行時にテキストボックスが消滅してしまっているようで、
    その為に参照先が消え、ReferenceErrorが出ているようです・・・


    Private Sub ProcessInputKey(ByRef m As Message)
    Const RidInput As Integer = &H10000003
    Dim headerSize As Integer _
    = Marshal.SizeOf(GetType(RawInputHeader))
    Dim size As Integer _
    = Marshal.SizeOf(GetType(RawInput))
    Dim input As RawInput
    GetRawInputData(m.LParam, RidInput, _
    input, size, headerSize)
    Dim mouse As RawMouse = input.Mouse
    'デバイスの番号と直前からの移動量を表示
    Me.m_textBox.AppendText( _
    String.Format("{0}({1},{2})" & Environment.NewLine, _
    input.Header.Device, _
    mouse.LastX, mouse.LastY))

    '変更箇所はこの部分のみ
    TextBox1.Text = mouse.LastX

    End Sub
記事No.64390 のレス /過去ログ108より / 関連記事表示
削除チェック/

■64670  TCP/IP通信について
□投稿者/ tomoya -(2012/12/15(Sat) 11:05:22)

    分類:[VB.NET/VB2005 以降] 

    お世話になります。
    現在、TCP/IP通信によってデータの送受信を行いたいと考えているのですが、
    PC側より相手機器にTCP/IP通信を行うとエラーが生じてしまいます。
    (PC側の開発環境はVisual Basic2010 Expressを利用しています。)

    相手機器は「ASCIIコード交信」を選択しているので、ASCIIコードに文字列を変換して
    送信しなければ行けないのだと思うのですが、そのための手法を教えていただきたく
    思っています。

    送信コマンドは、
    ”500000FF03FF000018001004010001M*0001000008”
    を送信したいと思っています。


    別の機器同士でのTCP/IP送受信は正常に完了するため、相手機器の設定は間違って
    いないと思います。
    PC側からオープンとクローズ処理は完了できるため、コマンドの送信方法が間違って
    いるものと考えています。

    説明下手で申し訳ありませんが、よろしくお願いいたします。
親記事 /過去ログ109より / 関連記事表示
削除チェック/

■64949  Re[1]: 【VB2005、VB.NET】構造体のコピーについて
□投稿者/ shu -(2013/01/24(Thu) 17:08:58)
    No64946 (コンバート後に悩む人 さん) に返信
    
    構造体定義:
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
        Public Structure typAAAA
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=2)> Public aaaa As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=3)> Public bbbb As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=5)> Public cccc As String
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=7)> Public dddd As String
        End Structure
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
        Public Structure typBBBB
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=100)> Public strB As String
        End Structure
    
    
    コピー:
            Dim b = New typBBBB() With {.strB = "11222333334444444"}
            Dim ptr As New IntPtr()
            ptr = Marshal.AllocHGlobal(10000)   '<---ここの数字は適当
            Marshal.StructureToPtr(b, ptr, False)
    
            Dim a As New typAAAA
            a = CType(Marshal.PtrToStructure(ptr, GetType(Form1.typAAAA)), typAAAA)
            Marshal.FreeHGlobal(ptr)
    
    こんな感じでどうでしょう?たぶん逆でも出来ると思います。
記事No.64946 のレス /過去ログ109より / 関連記事表示
削除チェック/

■64957  Re[7]: 【VB2005、VB.NET】構造体のコピーについて
□投稿者/ コンバート後に悩む人 -(2013/01/24(Thu) 19:09:31)
    shuさんの手法で試したらうまく成功しました。
    そこで、逆を試したところ以下の通りとなりました。

    Dim b = New typBBBB() With {.strB = "11222333334444444"}
    が、ステートメントの終わりを指定してください。という旨のビルドエラーとなるため
    以下のように書き換えました。

    Dim a As New typAAAA
    Dim ptr As New IntPtr()

    a.aaaa = "11"
    a.bbbb = "222"
    a.cccc = "33333"
    a.dddd = "4444444"

    ptr = Marshal.AllocHGlobal(10000) '<---ここの数字は適当
    Marshal.StructureToPtr(a, ptr, False)

    Dim b As New typBBBB
    b = CType(Marshal.PtrToStructure(ptr, GetType(typBBBB)), typBBBB)
    Marshal.FreeHGlobal(ptr)

    bの内容をみると1のみしかセットされていませんでした。
    a.aaaaの最初の1のみ設定された感じでしょうか。
    <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=2)> Public aaaa As String
    は、実質1バイトとしてみなしてるようで、+1しなければならないようです。

    bbbb.strB = "11222333334444444"
    とならず
    bbbb.strB = "1"
    となるため
    strBの宣言付近が問題あるのでしょうか。
    もうちょっと考えてみます。

記事No.64946 のレス /過去ログ109より / 関連記事表示
削除チェック/

■65511  Re[1]: ファイルの必要部分だけを取り出すプログラム
□投稿者/ shu -(2013/03/05(Tue) 08:08:28)
    No65510 (rinngo さん) に返信

    DirectoryInfo.GetFilesなどで該当ファイルを検索
    StreamReaderなどでファイルをひらき
    ReadLineやReadToEndでファイル内容を読込み
    (該当行が先頭部に集中しているならReadLine、ファイルの後ろの方に
    ある可能性も高いならReadToEndがよいと思います。今どきのPCであれば10000行程度なら
    十分読めるのではないでしょうか)
    行毎に解析し
    StreamWriterでファイルに書き出す

    といった感じです。
記事No.65510 のレス /過去ログ110より / 関連記事表示
削除チェック/

■65524  Re[2]: Vb6のバイナリファイルをVB.netで読み込み
□投稿者/ クロ -(2013/03/05(Tue) 17:40:30)
    No65521 (shu さん) に返信
    > ■No65520 (クロ さん) に返信
    >
    > Currencyは内部表現が8byte整数なのでInt64で読んでみてはどうでしょう?
    > String*30は30byteのByte配列で読込んでEncodingされた方がよいかと思います。
    Currencyは10000倍されているのですね。
    一旦ReadInt64で読み込むことでうまくできました。
    Byte配列については引き続きやってみます・・・
記事No.65520 のレス /過去ログ110より / 関連記事表示
削除チェック/

■66468  Re[3]: 特定環境でGridViewのチェックボックスが押せない
□投稿者/ Azulean -(2013/04/24(Wed) 22:26:40)
    (念のため)
    DataGridView に読み取り専用のデータを流しているとか、環境依存性の他に、データによる問題という可能性はないでしょうか。
記事No.66463 のレス /過去ログ112より / 関連記事表示
削除チェック/

■67069  Re[2]: Googleでlogout処理
□投稿者/ まこと -(2013/06/28(Fri) 15:52:42)
    No67056 (魔界の仮面弁士 さん) に返信
    > ■No67052 (まこと さん) に返信
    >>現在、SDKをダウンロードしてGoogleカレンダーにログインするまでは出来るようになりました。
    >
    > SDK というのは、.NET Framework に対するものですか?
    > http://www.microsoft.com/ja-jp/download/details.aspx?id=19988
    >
    > それとも、google API に関するものですか?
    > https://developers.google.com/google-apps/calendar/


    返信有難うございます!!

    説明不足で申し訳ないです・・・

    APIです。

    検索してもログインの方法は沢山記述されてるのですがlogoutの方法が自分では見つけられませんでした。

    ちなみにログインのソースは下記のとおりです。
    UAを変更するのは、IEのバージョンが低いとGoogleからエラー画面が帰ってくる為、UAを変更しています。


    string g_id = "グーグルログインID";
    string g_pw = "パスワード";
    string UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0)";
    string url02 = "https://accounts.google.com/Logout?continue=https%3A%2F%2Faccounts.google.com%2FServiceLoginAuth&il=true&zx=1ia9s6agnj34r"; //ログアウトアドレス

    [DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
    private static extern int UrlMkSetSessionOption(int dwOption, string str, int nLength, int dwReserved);
    [DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
    private static extern int UrlMkGetSessionOption(int dwOption, StringBuilder pBuffer, int dwBufferLength, ref int pdwBufferLength, int dwReserved);

    private void Form1_Load(object sender, EventArgs e)
    {
    // カレンダーサービスを作成
    CalendarService service = new CalendarService("companyName-applicationName-1");

    // 認証設定
    service.setUserCredentials(g_id, g_pw);
    const int URLMON_OPTION_USERAGENT = 0x10000001;
    string ua = "";

    //元のUserAgentを取得する。
    StringBuilder userAgent = new StringBuilder(255);
    int returnLength = 0;
    int result = UrlMkGetSessionOption(URLMON_OPTION_USERAGENT, userAgent, userAgent.Capacity, ref returnLength, 0);
    //取得したUserAgentに文字を付け加える
    ua = userAgent.ToString() + UserAgent;
    UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, ua, ua.Length, 0);
    this.webBrowser1.Navigate("https://www.google.com/calendar/embed?src=" + g_id + "&ctz=Asia/Tokyo");
    }
記事No.67052 のレス /過去ログ113より / 関連記事表示
削除チェック/

次の20件>

<< 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 >>

ヒット件数が多いので過去ログ104〜166 までの検索結果 / 過去ログ167からさらに検索→

パスワード/

- Child Tree -